├── jose └── testdata │ ├── oct.txt │ ├── empty.json │ ├── invalid.crt │ ├── passphrase.txt │ ├── oct.json │ ├── okp.pub.json │ ├── okp.priv.json │ ├── p256.pub.json │ ├── empty.jwks.json │ ├── p256.priv.json │ ├── oct.enc.json │ ├── rsa.pub.json │ ├── host-key.pub │ ├── ssh-ca.pub │ ├── okp.enc.priv.json │ ├── p256.enc.priv.json │ ├── jwks.json │ ├── rsa2048.crt │ ├── rsa.priv.json │ ├── bad-rsa.crt │ ├── rsa2048.key │ ├── bad-rsa.key │ ├── rsa.enc.priv.json │ └── host-key-cert.pub ├── kms ├── uri │ ├── testdata │ │ └── pin.txt │ ├── uri_other_test.go │ └── uri_119_test.go ├── cloudkms │ ├── testdata │ │ ├── ec.dat │ │ ├── aes.dat │ │ ├── rsa.dat │ │ ├── pub.pem │ │ └── rsapub.pem │ └── no_cloudkms.go ├── softkms │ └── testdata │ │ ├── nebula.pem │ │ ├── nebula.key │ │ ├── pub.pem │ │ ├── cert.key │ │ ├── priv.pem │ │ ├── dsa.pem │ │ ├── dsa.key │ │ ├── rsa.pub.pem │ │ ├── cert.crt │ │ └── rsa.priv.pem ├── sshagentkms │ ├── testdata │ │ ├── pub.pem │ │ ├── cert.key │ │ ├── priv.pem │ │ ├── cert.crt │ │ └── ssh.pub │ └── no_sshagentkms.go ├── tpmkms │ ├── testdata │ │ └── ec-tss2.pem │ ├── no_tpmkms.go │ ├── errors.go │ ├── tpmkms_others_test.go │ └── uri_test.go ├── capi │ ├── capi_no_windows.go │ └── no_capi.go ├── awskms │ └── no_awskms.go ├── azurekms │ ├── no_azurekms.go │ └── lazy_client.go ├── yubikey │ └── yubikey_no_cgo.go ├── mackms │ └── mackms_other.go ├── apiv1 │ ├── registry.go │ └── requests_test.go ├── pkcs11 │ ├── yubihsm2_test.go │ ├── softhsm2_test.go │ ├── opensc_test.go │ └── pkcs11_no_cgo.go ├── kms.go ├── object.go └── kms_test.go ├── pemutil └── testdata │ ├── password.txt │ ├── password2.txt │ ├── ca.der │ ├── test.der │ ├── badder.crt │ ├── bad.csr │ ├── pkcs8 │ ├── openssl.ed25519.der │ ├── openssl.ed25519.pub.der │ ├── openssl.ed25519.pem │ ├── openssl.ed25519.pub.pem │ ├── openssl.p256.pub.pem │ ├── openssl.p384.pub.pem │ ├── openssl.p256.pem │ ├── openssl.p521.pub.pem │ ├── openssl.ed25519.enc.pem │ ├── openssl.p384.pem │ ├── openssl.p521.pem │ ├── openssl.p256.enc.pem │ ├── openssl.p384.enc.pem │ ├── openssl.rsa2048.pub.pem │ ├── openssl.p521.enc.pem │ ├── openssl.rsa4096.pub.pem │ ├── openssl.rsa2048.pem │ └── openssl.rsa2048.enc.pem │ ├── openssh.ed25519.pub.pem │ ├── nebula.key │ ├── nebula.pub │ ├── openssh.p256.pub.pem │ ├── cosign.pub.pem │ ├── openssl.p256.pub.pem │ ├── openssh.p384.pub.pem │ ├── openssl.p384.pub.pem │ ├── openssh.rsa1024.pub.pem │ ├── openssl.p256.pem │ ├── cosign.pem │ ├── openssh.p521.pub.pem │ ├── openssl.p521.pub.pem │ ├── openssl.rsa1024.pub.pem │ ├── openssl.p384.pem │ ├── openssl.p256.enc.pem │ ├── badpem.csr │ ├── test.csr │ ├── keytool.csr │ ├── openssl.p521.pem │ ├── openssl.p384.enc.pem │ ├── openssh.rsa2048.pub.pem │ ├── openssh.ed25519.pem │ ├── badnebula.key │ ├── badnebula.pub │ ├── openssl.p521.enc.pem │ ├── openssh.ed25519.enc.pem │ ├── openssl.rsa2048.pub.pem │ ├── openssh.p256.pem │ ├── ca2.crt │ ├── openssh.p256.enc.pem │ ├── openssh.p384.pem │ ├── cosign.enc.pem │ ├── openssh.p384.enc.pem │ ├── openssh.p521.pem │ ├── openssh.p521.enc.pem │ ├── openssl.rsa1024.pem │ ├── openssl.rsa1024.enc.pem │ ├── openssh.rsa1024.pem │ ├── openssh.rsa1024.enc.pem │ ├── bundle-1st.crt │ ├── bundle-2nd.crt │ ├── openssl.rsa2048.pem │ ├── openssl.rsa2048.enc.pem │ ├── openssh.rsa2048.pem │ └── openssh.rsa2048.enc.pem ├── nssdb ├── Makefile ├── testdata │ ├── leaf.p12 │ ├── v3.107 │ │ ├── ids.txt │ │ ├── cert9.db │ │ ├── key4.db │ │ └── pkcs11.txt │ ├── v3.51 │ │ ├── ids.txt │ │ ├── key4.db │ │ ├── cert9.db │ │ └── pkcs11.txt │ ├── 3_107.Dockerfile │ ├── 3_51.Dockerfile │ ├── leaf.key │ ├── root-ca.key │ ├── Makefile │ ├── root-ca.crt │ ├── leaf.crt │ ├── README.md │ └── fixtures.sh ├── metadata_test.go ├── metadata.go ├── object.go └── sign_test.go ├── internal ├── utils │ ├── file │ │ └── testdata │ │ │ ├── pass1.txt │ │ │ └── pass2.txt │ ├── asn1 │ │ ├── asn1_test.go │ │ └── asn1.go │ └── convert │ │ ├── convert_test.go │ │ └── convert.go ├── emoji │ └── emoji_test.go ├── bcrypt_pbkdf │ ├── README │ └── LICENSE └── templates │ └── validate.go ├── tools.go ├── keyutil └── testdata │ ├── ed25519.pub │ ├── p256.pub │ └── rsa.pub ├── tpm ├── internal │ ├── open │ │ ├── open.go │ │ ├── open_windows.go │ │ └── open_others.go │ ├── socket │ │ ├── socket_windows.go │ │ ├── socket_others.go │ │ └── socket.go │ ├── close │ │ ├── close.go │ │ ├── close_windows.go │ │ └── close_others.go │ └── key │ │ ├── key_windows.go │ │ ├── create.go │ │ └── key_others.go ├── simulator │ ├── simulator.go │ └── simulator_disabled.go ├── tss2 │ ├── other_test.go │ ├── tpm_test.go │ ├── simulator_test.go │ └── encode.go ├── available │ └── check.go ├── rand │ ├── rand.go │ └── rand_simulator_test.go ├── attestation │ ├── useragent.go │ ├── testdata │ │ └── roots.pem │ └── requestid.go ├── storage │ ├── tpmstore_test.go │ ├── errors.go │ ├── blackhole.go │ ├── tpmstore.go │ ├── blackhole_test.go │ └── types_test.go ├── errors.go ├── names_test.go ├── caps_test.go ├── algorithm │ └── algorithm_test.go ├── context.go ├── names.go ├── tss2.go ├── manufacturer │ └── manufacturers_test.go ├── blobs.go ├── caps.go └── ak_test.go ├── .github ├── workflows │ ├── code-scan-cron.yml │ ├── dependabot-auto-merge.yml │ ├── triage.yml │ ├── ci.yml │ └── release.yml ├── ISSUE_TEMPLATE │ ├── enhancement.md │ ├── config.yml │ ├── documentation-request.md │ └── bug-report.yml ├── PULL_REQUEST_TEMPLATE └── dependabot.yml ├── fipsutil ├── fipsutil_test.go ├── fipsutil_other.go └── fipsutil.go ├── x509util ├── testdata │ ├── rawSubject.key │ ├── secrets │ │ └── example.key │ ├── opcua.tpl │ ├── rawSubject.tpl │ ├── rawSubject.csr │ ├── ed25519.crt │ ├── capath2 │ │ ├── root1.crt │ │ └── root2.crt │ ├── example.tpl │ ├── challengePasswordUTF8.csr │ ├── challengePassword.csr │ ├── capath │ │ └── cert.pem │ ├── letsencrypt.crt │ ├── fullsimple.tpl │ ├── rsa.key │ ├── google.crt │ └── smallstep.crt ├── certpool.go ├── certpool_test.go └── fingerprint.go ├── sshutil ├── testdata │ ├── date.tpl │ └── github.tpl ├── certificate_request.go └── types.go ├── .gitignore ├── SECURITY.md ├── tlsutil ├── utils.go ├── cache.go └── utils_test.go └── Makefile /jose/testdata/oct.txt: -------------------------------------------------------------------------------- 1 | a true random password -------------------------------------------------------------------------------- /kms/uri/testdata/pin.txt: -------------------------------------------------------------------------------- 1 | trim-this-pin 2 | -------------------------------------------------------------------------------- /pemutil/testdata/password.txt: -------------------------------------------------------------------------------- 1 | mypassword -------------------------------------------------------------------------------- /pemutil/testdata/password2.txt: -------------------------------------------------------------------------------- 1 | pass 2 | -------------------------------------------------------------------------------- /jose/testdata/empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "keys": [] 3 | } -------------------------------------------------------------------------------- /jose/testdata/invalid.crt: -------------------------------------------------------------------------------- 1 | this is not a valid certificate 2 | -------------------------------------------------------------------------------- /jose/testdata/passphrase.txt: -------------------------------------------------------------------------------- 1 | Supercalifragilisticexpialidocious -------------------------------------------------------------------------------- /nssdb/Makefile: -------------------------------------------------------------------------------- 1 | columns: 2 | go run generate/main.go > columns.go 3 | -------------------------------------------------------------------------------- /internal/utils/file/testdata/pass1.txt: -------------------------------------------------------------------------------- 1 | brandy-guidon-basin-ishmael-sedge-ducting -------------------------------------------------------------------------------- /nssdb/testdata/leaf.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/nssdb/testdata/leaf.p12 -------------------------------------------------------------------------------- /pemutil/testdata/ca.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/pemutil/testdata/ca.der -------------------------------------------------------------------------------- /internal/utils/file/testdata/pass2.txt: -------------------------------------------------------------------------------- 1 | benumb-eyepiece-stale-revers-marital-mimesis 2 | 3 | -------------------------------------------------------------------------------- /pemutil/testdata/test.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/pemutil/testdata/test.der -------------------------------------------------------------------------------- /kms/cloudkms/testdata/ec.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/kms/cloudkms/testdata/ec.dat -------------------------------------------------------------------------------- /nssdb/testdata/v3.107/ids.txt: -------------------------------------------------------------------------------- 1 | certificate 676985117 2 | public-key 676985115 3 | private-key 676985114 4 | -------------------------------------------------------------------------------- /nssdb/testdata/v3.51/ids.txt: -------------------------------------------------------------------------------- 1 | certificate 279438320 2 | public-key 279438318 3 | private-key 279438317 4 | -------------------------------------------------------------------------------- /nssdb/testdata/v3.51/key4.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/nssdb/testdata/v3.51/key4.db -------------------------------------------------------------------------------- /pemutil/testdata/badder.crt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/pemutil/testdata/badder.crt -------------------------------------------------------------------------------- /kms/cloudkms/testdata/aes.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/kms/cloudkms/testdata/aes.dat -------------------------------------------------------------------------------- /kms/cloudkms/testdata/rsa.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/kms/cloudkms/testdata/rsa.dat -------------------------------------------------------------------------------- /nssdb/testdata/v3.107/cert9.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/nssdb/testdata/v3.107/cert9.db -------------------------------------------------------------------------------- /nssdb/testdata/v3.107/key4.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/nssdb/testdata/v3.107/key4.db -------------------------------------------------------------------------------- /nssdb/testdata/v3.51/cert9.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/nssdb/testdata/v3.51/cert9.db -------------------------------------------------------------------------------- /tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | 3 | package crypto 4 | 5 | import ( 6 | _ "go.uber.org/mock/mockgen" 7 | ) 8 | -------------------------------------------------------------------------------- /pemutil/testdata/bad.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | Bad Certificate Request 3 | -----END CERTIFICATE REQUEST----- -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.ed25519.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/pemutil/testdata/pkcs8/openssl.ed25519.der -------------------------------------------------------------------------------- /jose/testdata/oct.json: -------------------------------------------------------------------------------- 1 | { 2 | "use": "sig", 3 | "kty": "oct", 4 | "alg": "HS256", 5 | "k": "TUE5VnJDa3gzbDRtc3lWa1liRW1pUDVZNHBBRnNUNXo" 6 | } -------------------------------------------------------------------------------- /pemutil/testdata/openssh.ed25519.pub.pem: -------------------------------------------------------------------------------- 1 | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFF/TpiUOL8JWcsQMxOXFYf44WiNHVjV3evDsa67UQpV mariano@endor.local 2 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.ed25519.pub.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/crypto/HEAD/pemutil/testdata/pkcs8/openssl.ed25519.pub.der -------------------------------------------------------------------------------- /keyutil/testdata/ed25519.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MCowBQYDK2VwAyEAZ/fKNzve1MQ802E86hmqnAFRg8HwVUSycSyD8UhBWp0= 3 | -----END PUBLIC KEY----- 4 | -------------------------------------------------------------------------------- /kms/softkms/testdata/nebula.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN NEBULA X25519 PUBLIC KEY----- 2 | fH8U8+JEY6azHXHOwRoburcf25WG/ueKxvQ7sQrUVA8= 3 | -----END NEBULA X25519 PUBLIC KEY----- 4 | -------------------------------------------------------------------------------- /pemutil/testdata/nebula.key: -------------------------------------------------------------------------------- 1 | -----BEGIN NEBULA X25519 PRIVATE KEY----- 2 | sc9k10IOJEFg9QDXEAFqkDgVQ3KfuubYHfG+Xl2ODbs= 3 | -----END NEBULA X25519 PRIVATE KEY----- 4 | -------------------------------------------------------------------------------- /pemutil/testdata/nebula.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN NEBULA X25519 PUBLIC KEY----- 2 | fH8U8+JEY6azHXHOwRoburcf25WG/ueKxvQ7sQrUVA8= 3 | -----END NEBULA X25519 PUBLIC KEY----- 4 | -------------------------------------------------------------------------------- /kms/softkms/testdata/nebula.key: -------------------------------------------------------------------------------- 1 | -----BEGIN NEBULA X25519 PRIVATE KEY----- 2 | sc9k10IOJEFg9QDXEAFqkDgVQ3KfuubYHfG+Xl2ODbs= 3 | -----END NEBULA X25519 PRIVATE KEY----- 4 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.ed25519.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MC4CAQAwBQYDK2VwBCIEINAZsM17htJYpUVv03/elGiJ7iIgli8tKZSYI8o8bE4W 3 | -----END PRIVATE KEY----- 4 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.ed25519.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MCowBQYDK2VwAyEAmNOXbqvXiA/oY2kQEox1afTNVHDTQJdTtw9vGvnKEko= 3 | -----END PUBLIC KEY----- 4 | -------------------------------------------------------------------------------- /tpm/internal/open/open.go: -------------------------------------------------------------------------------- 1 | package open 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | func TPM(deviceName string) (io.ReadWriteCloser, error) { 8 | return open(deviceName) 9 | } 10 | -------------------------------------------------------------------------------- /.github/workflows/code-scan-cron.yml: -------------------------------------------------------------------------------- 1 | on: 2 | schedule: 3 | - cron: '0 0 * * *' 4 | 5 | jobs: 6 | code-scan: 7 | uses: smallstep/workflows/.github/workflows/code-scan.yml@main 8 | -------------------------------------------------------------------------------- /nssdb/testdata/3_107.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:41 2 | 3 | RUN dnf install -y nss-tools sqlite 4 | 5 | COPY fixtures.sh /bin 6 | COPY leaf.p12 / 7 | 8 | RUN mkdir /nssdb 9 | WORKDIR /nssdb 10 | -------------------------------------------------------------------------------- /nssdb/testdata/3_51.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:30 2 | 3 | RUN dnf install -y nss-tools sqlite 4 | 5 | COPY fixtures.sh /bin 6 | COPY leaf.p12 / 7 | 8 | RUN mkdir /nssdb 9 | WORKDIR /nssdb 10 | -------------------------------------------------------------------------------- /tpm/simulator/simulator.go: -------------------------------------------------------------------------------- 1 | package simulator 2 | 3 | import "io" 4 | 5 | type Simulator interface { 6 | io.ReadWriteCloser 7 | Open() error 8 | MeasurementLog() ([]byte, error) 9 | } 10 | -------------------------------------------------------------------------------- /fipsutil/fipsutil_test.go: -------------------------------------------------------------------------------- 1 | package fipsutil 2 | 3 | import "testing" 4 | 5 | func TestFipsUtil(t *testing.T) { 6 | t.Log("fipsutil.Enabled() is", Enabled()) 7 | t.Log("fipsutil.Only() is", Only()) 8 | } 9 | -------------------------------------------------------------------------------- /keyutil/testdata/p256.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcoeNMyqS0/lveul4nVhxHAtpK2UJ 3 | Qkodxz3jSYKLr2u7Q5/0psUwFSmhUK4ZN+8TNKFJNV72HjAbFtcARH/WkA== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /kms/cloudkms/testdata/pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5VPD/W5RXn0lrs2MdoNteTSZ+sh1 3 | veT13hakPZF9YzaNVZgujqK3d1nt+4jPECU+ED/WQ1GgFZiVGUo3flvB/w== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /kms/softkms/testdata/pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5VPD/W5RXn0lrs2MdoNteTSZ+sh1 3 | veT13hakPZF9YzaNVZgujqK3d1nt+4jPECU+ED/WQ1GgFZiVGUo3flvB/w== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.p256.pub.pem: -------------------------------------------------------------------------------- 1 | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI3kt38MXLwskrTKtaD5HKGrj+J8evJDIJB5PhRdIH5QZ1Fy3uRYDSEBFtNpIKH7xT8azk74iQM2hMpWyDEpQxA= mariano@endor.local 2 | -------------------------------------------------------------------------------- /kms/sshagentkms/testdata/pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5VPD/W5RXn0lrs2MdoNteTSZ+sh1 3 | veT13hakPZF9YzaNVZgujqK3d1nt+4jPECU+ED/WQ1GgFZiVGUo3flvB/w== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /pemutil/testdata/cosign.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE26hpmcHa2CYaz7lgTWKLBNlSv2Ey 3 | PxSiLGG8y9Xk2WOXq2Wl1naPvrW55Z1fk+XeB1hepjoyJnG6Bj8M1l6XKg== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.p256.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEp2gPSjWPnX25PYBYpMjl+D2VAI2S 3 | mm1pxaMQw5x974BnEg25Axaf3yN//SwJ3X1Ju9gwfhhHmpqYKzQ/reyNOw== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /tpm/internal/socket/socket_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package socket 4 | 5 | import ( 6 | "io" 7 | ) 8 | 9 | func newSocket(_ string) (io.ReadWriteCloser, error) { 10 | return nil, ErrNotSupported 11 | } 12 | -------------------------------------------------------------------------------- /jose/testdata/okp.pub.json: -------------------------------------------------------------------------------- 1 | { 2 | "use": "sig", 3 | "kty": "OKP", 4 | "kid": "qiCJG7r2L80rmWRrZMPfpanQHmZRcncOG7A7MBWn9qM", 5 | "crv": "Ed25519", 6 | "alg": "EdDSA", 7 | "x": "L4WYxHsMVaspyhWuSp84v2meEYMEUdYnrn-w-jqP6iw" 8 | } -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.p256.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8OzWjsmw/B+d/LuJdPT0xDxgKjoJ 3 | R8u8CwRmRFeiMXK1FirRIo+YFJpdJ+x+RtpNaHYCpiCZr0GsKXtH0tkHVQ== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.p384.pub.pem: -------------------------------------------------------------------------------- 1 | ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBNlvZXMQ+zY03+LWod10pNV/CgirdN895D+RxYG+4JUl8jKC+mb0x66xrAQ+4tIRfCI0N7D5gdn3Eci8WMKZmwu4Q7O6H230qi3Aznsf7s35EMXOEzaPyEBo65PlcMsp9Q== mariano@endor.local 2 | -------------------------------------------------------------------------------- /tpm/internal/open/open_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package open 4 | 5 | import ( 6 | "io" 7 | 8 | "github.com/google/go-tpm/legacy/tpm2" 9 | ) 10 | 11 | func open(_ string) (io.ReadWriteCloser, error) { 12 | return tpm2.OpenTPM() 13 | } 14 | -------------------------------------------------------------------------------- /nssdb/testdata/leaf.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEINaSpIqOXutso06qUxRFBiKO7k2l/fNALIB5TkCWkOeLoAoGCCqGSM49 3 | AwEHoUQDQgAEhfpON/u7R3lMVcKtIrAG0/jXvvKq6TAnnfIa5/U//n2Tr0hOq2lK 4 | HgH/kBNKZvvfLI0tvtvZ5+uaSTdKh6EXxw== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /nssdb/testdata/root-ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIOeJBnB/zZO6y87vcooGf0tSlEVM94hVII+zYnsTRkF6oAoGCCqGSM49 3 | AwEHoUQDQgAEiQlr80Ez6Ma6NnlqFrEAeaksw/WfT66M5DkRk4HM1HuUvFVHQxb5 4 | BKCIYDZ+jvZpBHXv8ff8Jw2obRGOIJOwMg== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.p384.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEisIc1TXATL5v5arNdG9iNMLhHBCK6oGg 3 | tFfWN/roU8LrFGY1TzJh0lgTNmZ9dBWglxusqRxLIqozAOknSQTBpt28+JRvMD3T 4 | 5Pgfs1QO3IZ1C8wTrkoCKXnoarogiZv4 5 | -----END PUBLIC KEY----- 6 | -------------------------------------------------------------------------------- /kms/softkms/testdata/cert.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEICB6lIrMa9fVQJtdAYS4qmdYQ1BHJsEQDx8zxL38gA8toAoGCCqGSM49 3 | AwEHoUQDQgAE5VPD/W5RXn0lrs2MdoNteTSZ+sh1veT13hakPZF9YzaNVZgujqK3 4 | d1nt+4jPECU+ED/WQ1GgFZiVGUo3flvB/w== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.rsa1024.pub.pem: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDfgz0N32eMQMILbjdo/CdndvIC3r7L12Ch0IO77B4g2aW7Mai1jNx/Hrz7ssvSujypbw6d8TBmNszbp+J4coVHgdZZuz8sKpAKmiNgZVqtp2+SzTsPpzGvfxsIcPOLEk+2MHdUdhLWacB35ifqSW9tY2E1nA/XVub/pPFp5dccxQ== mariano@endor.local 2 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.p384.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEpuWwDeKVd2fiP9FXacyoXTzmN/NbQZMJ 3 | QR9tVof5m3e5BZnpfbUOosbFHskfF+XU1s7oI2yeIET2QbmSZ1YJW1wvz9aGrsU2 4 | YS7VfczIwfUqpVk4ap2FkcEGclpdLfR4 5 | -----END PUBLIC KEY----- 6 | -------------------------------------------------------------------------------- /kms/sshagentkms/testdata/cert.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEICB6lIrMa9fVQJtdAYS4qmdYQ1BHJsEQDx8zxL38gA8toAoGCCqGSM49 3 | AwEHoUQDQgAE5VPD/W5RXn0lrs2MdoNteTSZ+sh1veT13hakPZF9YzaNVZgujqK3 4 | d1nt+4jPECU+ED/WQ1GgFZiVGUo3flvB/w== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.p256.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIOWt6OMAASXS1jJ/Sn2vY8ciPDU74cqjq3J13oYUNeNuoAoGCCqGSM49 3 | AwEHoUQDQgAEp2gPSjWPnX25PYBYpMjl+D2VAI2Smm1pxaMQw5x974BnEg25Axaf 4 | 3yN//SwJ3X1Ju9gwfhhHmpqYKzQ/reyNOw== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /x509util/testdata/rawSubject.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIK9FBgwqr6Zjsbf2uPmvnDz341AhiJbPLTuq8+/BLbd/oAoGCCqGSM49 3 | AwEHoUQDQgAExjS2bc7+XXJdjc+ulwVfrauYygh/Vhj5bLgRKuPDTVG9S83nI2lU 4 | 2bBMHvmaUG585ME3WFxSOvB26L8VnPXw8Q== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /jose/testdata/okp.priv.json: -------------------------------------------------------------------------------- 1 | { 2 | "use": "sig", 3 | "kty": "OKP", 4 | "kid": "qiCJG7r2L80rmWRrZMPfpanQHmZRcncOG7A7MBWn9qM", 5 | "crv": "Ed25519", 6 | "alg": "EdDSA", 7 | "x": "L4WYxHsMVaspyhWuSp84v2meEYMEUdYnrn-w-jqP6iw", 8 | "d": "kqyKV4yXV8viKLPp4HazFzvBkZi0wMKZ3iLXwtWqgvA" 9 | } -------------------------------------------------------------------------------- /pemutil/testdata/cosign.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgTJZPa2U7YR7hhEui 3 | 91pZ8qtW9dtqllRv8NdRmQ8LpTihRANCAATbqGmZwdrYJhrPuWBNYosE2VK/YTI/ 4 | FKIsYbzL1eTZY5erZaXWdo++tbnlnV+T5d4HWF6mOjImcboGPwzWXpcq 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /tpm/tss2/other_test.go: -------------------------------------------------------------------------------- 1 | //go:build !tpm && !tpmsimulator 2 | 3 | package tss2 4 | 5 | import ( 6 | "io" 7 | "testing" 8 | ) 9 | 10 | func openTPM(t *testing.T) io.ReadWriteCloser { 11 | t.Helper() 12 | t.Skip("Use tags tpm or tpmsimulator") 13 | return nil 14 | } 15 | -------------------------------------------------------------------------------- /jose/testdata/p256.pub.json: -------------------------------------------------------------------------------- 1 | { 2 | "use": "sig", 3 | "kty": "EC", 4 | "kid": "V93A-Yh7Bhw1W2E0igFciviJzX4PXPswoVgriehm9Co", 5 | "crv": "P-256", 6 | "alg": "ES256", 7 | "x": "JtPSvIKayHsCHobDnNWtOdoroh-MDwKQSYMW6Mo4cfU", 8 | "y": "tP7xR5rpu6azzZsozdmzouyVByuTUDYSSAELTOAtu7g" 9 | } -------------------------------------------------------------------------------- /x509util/testdata/secrets/example.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgel8C9Xs8cZgTSIHw 3 | w7wEM7P2u3q2P0N+lvfQsjG4BWWhRANCAAQzxWGn3QiwUi7Y12Xr9DxByaUcmIS4 4 | hVIzhsfw8W4ntCxplH1pVPACIe3vY475froHYXKNwqFhFKAQrg/UvfQ7 5 | -----END PRIVATE KEY----- -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement 3 | about: Suggest an enhancement to step crypto 4 | title: '' 5 | labels: enhancement, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### What would you like to be added? 11 | 12 | 13 | ### Why this is needed 14 | -------------------------------------------------------------------------------- /sshutil/testdata/date.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "type": "{{ .Type }}", 3 | "keyId": "{{ .KeyID }}", 4 | "principals": {{ toJson .Principals }}, 5 | "extensions": {{ toJson .Extensions }}, 6 | "validAfter": {{ now | toJson }}, 7 | "validBefore": {{ now | dateModify .Webhooks.Test.validity | toJson }} 8 | } -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.p256.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg0hcauzNATPOmA78k 3 | qNg8a83QKdQL5nb5ZrF6n3SN2hOhRANCAATw7NaOybD8H538u4l09PTEPGAqOglH 4 | y7wLBGZEV6IxcrUWKtEij5gUml0n7H5G2k1odgKmIJmvQawpe0fS2QdV 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.p521.pub.pem: -------------------------------------------------------------------------------- 1 | ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAErMjdBKnVrZ7XMy6VmXW4UXVjYOe8tIjAS7zfuE5XV6lgSA294CEY2bntO4Gpi2dl5V93anNrPsIpfo3gHfc3VcAFDk2COLuUXZ1RuaE2omgyHjeKgixA0FoF6eGZGlg/p/mTw//slkwiwuGQmTaHKRvyZpJn4Hc9jA8w0F1K8/7SwdA== mariano@endor.local 2 | -------------------------------------------------------------------------------- /jose/testdata/empty.jwks.json: -------------------------------------------------------------------------------- 1 | { 2 | "keys": [ 3 | { 4 | "use": "sig", 5 | "kty": "OKP", 6 | "kid": "qiCJG7r2L80rmWRrZMPfpanQHmZRcncOG7A7MBWn9qM", 7 | "crv": "Ed25519", 8 | "alg": "EdDSA", 9 | "x": "kqyKV4yXV8viKLPp4HazFzvBkZi0wMKZ3iLXwtWqgvA" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /.github/workflows/dependabot-auto-merge.yml: -------------------------------------------------------------------------------- 1 | name: Dependabot auto-merge 2 | on: pull_request 3 | 4 | permissions: 5 | contents: write 6 | pull-requests: write 7 | 8 | jobs: 9 | dependabot-auto-merge: 10 | uses: smallstep/workflows/.github/workflows/dependabot-auto-merge.yml@main 11 | secrets: inherit 12 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.p521.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBZuarpQvJAZrkK0MZf+99DoO2uF44 3 | TSdKQBLZl3qiMglGl4EmpIexE/73swIUsWHkRbhf8XJ2TDoFVV+iGJ26/pQAuus8 4 | tAqL2ft0DU5sosBEIox8dZ/D15rksEutGWE3PQ4ovx7Nw3+tMVP4hHTr/l7Sas4W 5 | 3roQ9SlNVSLdhHALuiI= 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.rsa1024.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCztZjbIWsnC88Npdq6YHwKi41O 3 | YPM8wD4Bcn7TU4NcEh5zLiQ9rpxoAxKmxZtSFD7PbTkQkNa8rHN5vX9qWrrwrAIx 4 | X/vAiVo+ZvSNoPeG1Bn18xJ34oLPUUv3IkVCSBFWcZ1NBUhde+KabeaGKNb3bHM+ 5 | 4btBb4TLZwhh6EC6RwIDAQAB 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.p521.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAkcu8lOt7MXmxr/Tj0F6ayc/TFwpe 3 | N60cMK0bg2kiAP1/eM0xtXsGqzTtdiRI3QPFLrOW3UT1wPPJxg++U2a9vHcBiIX/ 4 | F1ouynRxyoFk6irLNo1OoGoIE1VSUAxZ6SvEpBZMHPqNcWyCv1JFgPCTKI43aD9q 5 | oOiNJ+XyVGOnbMzCsO4= 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /tpm/internal/close/close.go: -------------------------------------------------------------------------------- 1 | package closer 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/smallstep/go-attestation/attest" 7 | ) 8 | 9 | func RWC(rwc io.ReadWriteCloser) error { 10 | return closeRWC(rwc) 11 | } 12 | 13 | func AttestTPM(t *attest.TPM, c *attest.OpenConfig) error { 14 | return attestTPM(t, c) 15 | } 16 | -------------------------------------------------------------------------------- /tpm/available/check.go: -------------------------------------------------------------------------------- 1 | package available 2 | 3 | import ( 4 | "fmt" 5 | 6 | "go.step.sm/crypto/tpm" 7 | ) 8 | 9 | func Check(opts ...tpm.NewTPMOption) error { 10 | t, err := tpm.New(opts...) 11 | if err != nil { 12 | return fmt.Errorf("failed creating TPM instance: %w", err) 13 | } 14 | return t.Available() 15 | } 16 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.p384.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MIGkAgEBBDBWB93doUgi7ZK78Q0ORM7RB9oSqT3cVb6HZvt7fF+/1Vj03Q8UlHSL 3 | Mf+4znN/hmSgBwYFK4EEACKhZANiAASKwhzVNcBMvm/lqs10b2I0wuEcEIrqgaC0 4 | V9Y3+uhTwusUZjVPMmHSWBM2Zn10FaCXG6ypHEsiqjMA6SdJBMGm3bz4lG8wPdPk 5 | +B+zVA7chnULzBOuSgIpeehquiCJm/g= 6 | -----END EC PRIVATE KEY----- 7 | -------------------------------------------------------------------------------- /jose/testdata/p256.priv.json: -------------------------------------------------------------------------------- 1 | { 2 | "use": "sig", 3 | "kty": "EC", 4 | "kid": "V93A-Yh7Bhw1W2E0igFciviJzX4PXPswoVgriehm9Co", 5 | "crv": "P-256", 6 | "alg": "ES256", 7 | "x": "JtPSvIKayHsCHobDnNWtOdoroh-MDwKQSYMW6Mo4cfU", 8 | "y": "tP7xR5rpu6azzZsozdmzouyVByuTUDYSSAELTOAtu7g", 9 | "d": "lgzkahW28vY8qXRFQd_Uphvl0Rfs9GyOj_ICkwy4V4s" 10 | } -------------------------------------------------------------------------------- /x509util/testdata/opcua.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "subject": {{ toJson .Subject }}, 3 | "sans": {{ toJson .SANs }}, 4 | "basicConstraints": { 5 | "isCA": false 6 | }, 7 | "keyUsage": ["digitalSignature", "keyEncipherment", "keyAgreement", "certSign"], 8 | "extKeyUsage": ["serverAuth", "clientAuth"] 9 | } 10 | -------------------------------------------------------------------------------- /sshutil/testdata/github.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "type": "{{ .Type }}", 3 | "keyId": "{{ .KeyID }}", 4 | "principals": {{ toJson .Principals }}, 5 | {{- if .Insecure.User.username }} 6 | "extensions": {{ set .Extensions "login@github.com" .Insecure.User.username | toJson }} 7 | {{- else }} 8 | "extensions": {{ toJson .Extensions }} 9 | {{- end }} 10 | } -------------------------------------------------------------------------------- /tpm/internal/open/open_others.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | 3 | package open 4 | 5 | import ( 6 | "io" 7 | 8 | "github.com/google/go-tpm/legacy/tpm2" 9 | ) 10 | 11 | func open(deviceName string) (io.ReadWriteCloser, error) { 12 | if deviceName == "" { 13 | return tpm2.OpenTPM() 14 | } 15 | 16 | return tpm2.OpenTPM(deviceName) 17 | } 18 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.ed25519.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED PRIVATE KEY----- 2 | MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAimMqAUr+eBzAICCAAw 3 | DAYIKoZIhvcNAgkFADAdBglghkgBZQMEARYEEK2t0HKcUFKSu1pwR7ZCl30EQMSR 4 | 6LXhyI0/z6Jt8EFAD261ZxAXFM78FO8Gz2KaVZ4vVSnOHihH/1jczpjZ1S+ZD+wI 5 | pqobcm9pMP89P1OfYEo= 6 | -----END ENCRYPTED PRIVATE KEY----- 7 | -------------------------------------------------------------------------------- /tpm/rand/rand.go: -------------------------------------------------------------------------------- 1 | package rand 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | 7 | "go.step.sm/crypto/tpm" 8 | ) 9 | 10 | func New(opts ...tpm.NewTPMOption) (io.Reader, error) { 11 | t, err := tpm.New(opts...) 12 | if err != nil { 13 | return nil, fmt.Errorf("failed creating TPM instance: %w", err) 14 | } 15 | return t.RandomReader() 16 | } 17 | -------------------------------------------------------------------------------- /nssdb/testdata/Makefile: -------------------------------------------------------------------------------- 1 | v3.107: 2 | mkdir v3.107 3 | docker build -t nssdb-v3.107 -f 3_107.Dockerfile . 4 | docker run --rm -it --volume ./v3.107:/nssdb nssdb-v3.107 /bin/fixtures.sh 5 | 6 | v3.51: 7 | mkdir v3.51 8 | docker build -t nssdb-v3.51 -f 3_51.Dockerfile . 9 | docker run --rm -it --volume ./v3.51:/nssdb nssdb-v3.51 /bin/fixtures.sh 10 | -------------------------------------------------------------------------------- /.github/workflows/triage.yml: -------------------------------------------------------------------------------- 1 | name: Add Issues and PRs to Triage 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | - reopened 8 | pull_request_target: 9 | types: 10 | - opened 11 | - reopened 12 | 13 | jobs: 14 | triage: 15 | uses: smallstep/workflows/.github/workflows/triage.yml@main 16 | secrets: inherit 17 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.p384.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCwBhXp1lcvaNt/mOGX 3 | cZGK/UE/WHPYd9ij0Iczk+AiPK2UvIGyXgVuGAaTyhw4ZTyhZANiAASm5bAN4pV3 4 | Z+I/0VdpzKhdPOY381tBkwlBH21Wh/mbd7kFmel9tQ6ixsUeyR8X5dTWzugjbJ4g 5 | RPZBuZJnVglbXC/P1oauxTZhLtV9zMjB9SqlWThqnYWRwQZyWl0t9Hg= 6 | -----END PRIVATE KEY----- 7 | -------------------------------------------------------------------------------- /tpm/internal/close/close_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package closer 4 | 5 | import ( 6 | "io" 7 | 8 | "github.com/smallstep/go-attestation/attest" 9 | ) 10 | 11 | func closeRWC(rwc io.ReadWriteCloser) error { 12 | return rwc.Close() 13 | } 14 | 15 | func attestTPM(t *attest.TPM, _ *attest.OpenConfig) error { 16 | return t.Close() 17 | } 18 | -------------------------------------------------------------------------------- /kms/softkms/testdata/priv.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: AES-256-CBC,1fcec5dfbf3327f61bfe5ab6ae8a0626 4 | 5 | V39b/pNHMbP80TXSHLsUY6UOTCzf3KwIxvj1e7S9brNMJJc9b3UiloMBJIYBkl00 6 | NKI8JU4jSlcerR58DqsTHIELiX6a+RJLe3/iR2/5Gru+CmmWJ68jQu872WCgh6Ms 7 | o8TzhyGx74ETmdKn5CdtylsnKMa9heW3tBLFAbNCgKc= 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /x509util/testdata/rawSubject.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "rawSubject": {{ toJson .Insecure.CR.RawSubject }}, 3 | "sans": {{ toJson .SANs }}, 4 | {{- if typeIs "*rsa.PublicKey" .Insecure.CR.PublicKey }} 5 | "keyUsage": ["keyEncipherment", "digitalSignature"], 6 | {{- else }} 7 | "keyUsage": ["digitalSignature"], 8 | {{- end }} 9 | "extKeyUsage": ["serverAuth", "clientAuth"] 10 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Ask on Discord 4 | url: https://discord.gg/7xgjhVAg6g 5 | about: You can ask for help here! 6 | - name: Want to contribute to step crypto? 7 | url: https://github.com/smallstep/cli/blob/master/docs/CONTRIBUTING.md 8 | about: Be sure to read contributing guidelines! 9 | -------------------------------------------------------------------------------- /kms/sshagentkms/testdata/priv.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: AES-256-CBC,1fcec5dfbf3327f61bfe5ab6ae8a0626 4 | 5 | V39b/pNHMbP80TXSHLsUY6UOTCzf3KwIxvj1e7S9brNMJJc9b3UiloMBJIYBkl00 6 | NKI8JU4jSlcerR58DqsTHIELiX6a+RJLe3/iR2/5Gru+CmmWJ68jQu872WCgh6Ms 7 | o8TzhyGx74ETmdKn5CdtylsnKMa9heW3tBLFAbNCgKc= 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.p256.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: AES-256-CBC,012738AA5F159CFF1B32511C1D29BCE8 4 | 5 | ocEZDAVsZ4edbcDBHUFOgyr++IDmwEz07ECteySu8je7bwTnAqLDx++/EgydGhPx 6 | K8ndFV8t5yEUzA564+KhnkEGm2xIK/PKvy+JmkbbzwQWkt23rcVPE3ARBDhjGGaA 7 | 49pFIdMhRk/KeszzCsWWizAMaM27B7uGMheRWein3tc= 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /tpm/tss2/tpm_test.go: -------------------------------------------------------------------------------- 1 | //go:build tpm 2 | 3 | package tss2 4 | 5 | import ( 6 | "io" 7 | "testing" 8 | 9 | "github.com/google/go-tpm/legacy/tpm2" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func openTPM(t *testing.T) io.ReadWriteCloser { 14 | t.Helper() 15 | 16 | rwc, err := tpm2.OpenTPM() 17 | require.NoError(t, err) 18 | return rwc 19 | } 20 | -------------------------------------------------------------------------------- /pemutil/testdata/badpem.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MAHYMIGAAgEAMB4xHDAaBgNVBAMTE2hlbGxvLnNtYWxsc3RlcC5jb20wWTATBgcq 3 | hkjOPQIBBggqhkjOPQMBBwNCAASKj0MvK6CUzFqRLfDTQNQp0Zt5dcHYx+Dq1Wh9 4 | 5dhqf1Fu9+1m5+LKkgBWoZmo7sJH0RuSjIdv/sZwpBrkdn2soAAwCgYIKoZIzj0E 5 | AwIDRwAwRAIgZgz9gdx9inOp6bSX4EkYiUCyLV9xGvabovu5C9UkRr8CIBGBbkp0 6 | l4tesAKoXelsLygJjPuUGRLK+OtdjPBIN1Zo 7 | -----END CERTIFICATE REQUEST----- -------------------------------------------------------------------------------- /pemutil/testdata/test.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIHYMIGAAgEAMB4xHDAaBgNVBAMTE2hlbGxvLnNtYWxsc3RlcC5jb20wWTATBgcq 3 | hkjOPQIBBggqhkjOPQMBBwNCAASKj0MvK6CUzFqRLfDTQNQp0Zt5dcHYx+Dq1Wh9 4 | 5dhqf1Fu9+1m5+LKkgBWoZmo7sJH0RuSjIdv/sZwpBrkdn2soAAwCgYIKoZIzj0E 5 | AwIDRwAwRAIgZgz9gdx9inOp6bSX4EkYiUCyLV9xGvabovu5C9UkRr8CIBGBbkp0 6 | l4tesAKoXelsLygJjPuUGRLK+OtdjPBIN1Zo 7 | -----END CERTIFICATE REQUEST----- -------------------------------------------------------------------------------- /pemutil/testdata/keytool.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN NEW CERTIFICATE REQUEST----- 2 | MIHYMIGAAgEAMB4xHDAaBgNVBAMTE2hlbGxvLnNtYWxsc3RlcC5jb20wWTATBgcq 3 | hkjOPQIBBggqhkjOPQMBBwNCAASKj0MvK6CUzFqRLfDTQNQp0Zt5dcHYx+Dq1Wh9 4 | 5dhqf1Fu9+1m5+LKkgBWoZmo7sJH0RuSjIdv/sZwpBrkdn2soAAwCgYIKoZIzj0E 5 | AwIDRwAwRAIgZgz9gdx9inOp6bSX4EkYiUCyLV9xGvabovu5C9UkRr8CIBGBbkp0 6 | l4tesAKoXelsLygJjPuUGRLK+OtdjPBIN1Zo 7 | -----END NEW CERTIFICATE REQUEST----- -------------------------------------------------------------------------------- /pemutil/testdata/openssl.p521.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MIHcAgEBBEIAZN3UZLUtCo0LFftfdbzcmEz49jtKcnuPQ+wi9ndf+W16oihuEUay 3 | 589hKy9MPSzuR2dv4+9NMLBlMS/wqg9DsMegBwYFK4EEACOhgYkDgYYABAFm5qul 4 | C8kBmuQrQxl/730Og7a4XjhNJ0pAEtmXeqIyCUaXgSakh7ET/vezAhSxYeRFuF/x 5 | cnZMOgVVX6IYnbr+lAC66zy0CovZ+3QNTmyiwEQijHx1n8PXmuSwS60ZYTc9Dii/ 6 | Hs3Df60xU/iEdOv+XtJqzhbeuhD1KU1VIt2EcAu6Ig== 7 | -----END EC PRIVATE KEY----- 8 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.p384.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-CBC,E2C4C65A352DD9CC 4 | 5 | KohSa6rhfwyxLJYP615pxiDMjN0l0J8s2tbazOWoQkIRQIuJlU4AhL4zBlmKhzZW 6 | V9hTSI2cJf7MRI0FX34sazGfBpVHxEDYzU69igWxani2n7Jqysgu1qdPmrfVKs8A 7 | TEM3ihDg/A1YFh5H7Coe3yeMfR7CGKZN5bY+jD2uyiUmiy+7/JsYBsQ+YJeR9RYP 8 | adOARAvJzMyVMUmBG6VNGewnftUfDGxj 9 | -----END EC PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /kms/softkms/testdata/dsa.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIHwMIGoBgcqhkjOOAQBMIGcAkEAjcm6Okl66tWbbD068ymE17XI0wLNUpcIZgoC 3 | qvV24qRMT6cTl/J10DYkR/vTZaJ8EufEidCEf0ZHD06WoORE3QIVAI8EK3wRHdGm 4 | IX5AHBuhfj/7p3xTAkBp8s2KAL/MsA1CINi3sOiVlbYPrA/WC9joLgV257BzOYLl 5 | WfZqiyketoSsd6sdkZUqVJ02FxxLqSv8jouMWtOLA0MAAkA+ye7vjsTNnIV2xDkc 6 | iQtnK1n4Di3DR15Tm0UPKf03FPxvYobFvCDxdgdlSAxDvjcDn1Z1ot7wzXFQX5IK 7 | 4ApU 8 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /tpm/attestation/useragent.go: -------------------------------------------------------------------------------- 1 | package attestation 2 | 3 | import "net/http" 4 | 5 | // UserAgent is the value of the User-Agent HTTP header that will 6 | // be set in HTTP requests to the attestation CA. 7 | var UserAgent = "step-attestation-http-client/1.0" 8 | 9 | // setUserAgent sets the User-Agent header in HTTP requests. 10 | func setUserAgent(r *http.Request) { 11 | r.Header.Set("User-Agent", UserAgent) 12 | } 13 | -------------------------------------------------------------------------------- /jose/testdata/oct.enc.json: -------------------------------------------------------------------------------- 1 | { 2 | "protected": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6ImpFUURBanFfVWx2WXZPNDZ0R2JxN1EifQ", 3 | "encrypted_key": "RAlAOaVm7ycTK2lQz90ltiJfrBpLq8Ze", 4 | "iv": "3PLGXbsdIyvMRAzi", 5 | "ciphertext": "HiLoDqUWM7TLOeEH2ihUpFMELS0OM1_0ZHb2dIA5W9HfEIsz7WAbPyTDA7iCCAJNr6NkEm8yYCKzQyhmcYhw-lU9fJ1HqfoiyPh1Bl56uiNRHnD_MeTEqKE", 6 | "tag": "j1T3WboWkkygIW53QxPG0g" 7 | } -------------------------------------------------------------------------------- /pemutil/testdata/openssh.rsa2048.pub.pem: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCum4bMH4Bm/vkPlk/qbBMrFlYUzVlUQnsBYunNREZb7itdBRau9nujSYhTbdtwMgH0gEnXp9gj/Hcvz3YdGYM/cOXZ334CbmTQ0cqiV90d2Qf03zDZS7ezv7Kamq0vdkA0Npw5lTOmZKnQcNibBAqcp2BeKSDIYGMTZMsEHOHsPX9jdwpEU4QevKAszjTF/UaPNLVpfMsEPuV9D8l02GPVg8HZXMNZt483nnN3MMnEqIuqRurEHz7xS9U5Rtqf45cQeFEcDXJa2ggVmLVfpHim4qHReA3qSz5QigvAR0I3XrBKv5MhLH0NPDawzeAgF0HR18CAkp+/KAP3CA6FXWWt mariano@endor.local 2 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.p521.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIA0ZySeLG4w9CzFj51 3 | CFLw5n1ArFHE8/5CTA0oXXDo/YPKA1mPMho84UZfz1hEXmgJLVq/XEnYjlj/yf57 4 | ITuYn4yhgYkDgYYABACRy7yU63sxebGv9OPQXprJz9MXCl43rRwwrRuDaSIA/X94 5 | zTG1ewarNO12JEjdA8Uus5bdRPXA88nGD75TZr28dwGIhf8XWi7KdHHKgWTqKss2 6 | jU6gaggTVVJQDFnpK8SkFkwc+o1xbIK/UkWA8JMojjdoP2qg6I0n5fJUY6dszMKw 7 | 7g== 8 | -----END PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /kms/softkms/testdata/dsa.key: -------------------------------------------------------------------------------- 1 | -----BEGIN DSA PRIVATE KEY----- 2 | MIH3AgEAAkEAjcm6Okl66tWbbD068ymE17XI0wLNUpcIZgoCqvV24qRMT6cTl/J1 3 | 0DYkR/vTZaJ8EufEidCEf0ZHD06WoORE3QIVAI8EK3wRHdGmIX5AHBuhfj/7p3xT 4 | AkBp8s2KAL/MsA1CINi3sOiVlbYPrA/WC9joLgV257BzOYLlWfZqiyketoSsd6sd 5 | kZUqVJ02FxxLqSv8jouMWtOLAkA+ye7vjsTNnIV2xDkciQtnK1n4Di3DR15Tm0UP 6 | Kf03FPxvYobFvCDxdgdlSAxDvjcDn1Z1ot7wzXFQX5IK4ApUAhRIG+8uWBKim3Rc 7 | iUyGbE4gL/XByA== 8 | -----END DSA PRIVATE KEY----- -------------------------------------------------------------------------------- /kms/tpmkms/testdata/ec-tss2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN TSS2 PRIVATE KEY----- 2 | MIHyBgZngQUKAQOgAwEB/wIEQAAAAQRaAFgAIwALAAQAcgAAABAAGAALAAMAEAAg 3 | ebLnGlDAN5aHdkffRTqBdsQNnO60aY+Xvg5u80sIauMAIM0E3zndp5392TPBroKz 4 | PLHEwLiUVeBmOhBG3kss/uICBIGAAH4AIIMO322TFYndManhpvTgLMiFd6Vs3HVs 5 | OrHb15qLZTDQABBMcF+L3C2322FU060DHXv56Uq87uMu/qWE3HU+r5856+70P94I 6 | 0z3Plxwln2iGhhbKZ8gQQNKhiOdE4MYDPnN1uqvcwJwd7NZ1fqnwBKks6E1vgSne 7 | tYeNooQ= 8 | -----END TSS2 PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /nssdb/testdata/v3.107/pkcs11.txt: -------------------------------------------------------------------------------- 1 | library= 2 | name=NSS Internal PKCS #11 Module 3 | parameters=configdir='.' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' 4 | NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30}) 5 | 6 | -------------------------------------------------------------------------------- /nssdb/testdata/v3.51/pkcs11.txt: -------------------------------------------------------------------------------- 1 | library= 2 | name=NSS Internal PKCS #11 Module 3 | parameters=configdir='.' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' 4 | NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30}) 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Go Workspaces 9 | go.work 10 | go.work.sum 11 | 12 | # Development 13 | .vscode/ 14 | coverage.cov 15 | 16 | # Test binary, built with `go test -c` 17 | *.test 18 | 19 | # Output of the go coverage tool, specifically when used with LiteIDE 20 | *.out 21 | 22 | # Dependency directories (remove the comment below to include it) 23 | /vendor 24 | -------------------------------------------------------------------------------- /kms/capi/capi_no_windows.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | 3 | package capi 4 | 5 | import ( 6 | "context" 7 | 8 | "github.com/pkg/errors" 9 | "go.step.sm/crypto/kms/apiv1" 10 | ) 11 | 12 | func init() { 13 | apiv1.Register(apiv1.CAPIKMS, func(ctx context.Context, opts apiv1.Options) (apiv1.KeyManager, error) { 14 | return nil, errors.Errorf("unsupported kms type 'capi': CAPI/nCrypt is only available on Windows, and not in WSL") 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.p256.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED PRIVATE KEY----- 2 | MIHsMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjea/b6VGV6vgICCAAw 3 | DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEH0EKFq/7EHfDn929+26c5gEgZA4 4 | h4GTx9vjJXCuGi3TF+dnqfGLlzWzmxtYZLjoCim2R3L55UTJCUpH7D6Zi1q6kR5r 5 | IinvijgKJUkqQCriOfBp6iZr5QDxbAy7aysJL5HrhOkFAH3TlK+3p3gclm7OEMoH 6 | 2vD/i+QgmLjq/gKyo1pcXUhguq5zrjPHsj9Tp365EU5VgavR7nVXYtJZW86KQlA= 7 | -----END ENCRYPTED PRIVATE KEY----- 8 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.ed25519.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW 3 | QyNTUxOQAAACBRf06YlDi/CVnLEDMTlxWH+OFojR1Y1d3rw7Guu1EKVQAAAJgG8EtjBvBL 4 | YwAAAAtzc2gtZWQyNTUxOQAAACBRf06YlDi/CVnLEDMTlxWH+OFojR1Y1d3rw7Guu1EKVQ 5 | AAAECHHCRxaxuDUzPhwiXZovjvMLYkLiSx+ho3b+9gavl031F/TpiUOL8JWcsQMxOXFYf4 6 | 4WiNHVjV3evDsa67UQpVAAAAE21hcmlhbm9AZW5kb3IubG9jYWwBAg== 7 | -----END OPENSSH PRIVATE KEY----- 8 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | We appreciate any effort to discover and disclose security vulnerabilities responsibly. 2 | 3 | If you would like to report a vulnerability in one of our projects, or have security concerns regarding Smallstep software, please email security@smallstep.com. 4 | 5 | In order for us to best respond to your report, please include any of the following: 6 | * Steps to reproduce or proof-of-concept 7 | * Any relevant tools, including versions used 8 | * Tool output 9 | -------------------------------------------------------------------------------- /pemutil/testdata/badnebula.key: -------------------------------------------------------------------------------- 1 | -----BEGIN NEBULA X25519 PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW 3 | QyNTUxOQAAACBRf06YlDi/CVnLEDMTlxWH+OFojR1Y1d3rw7Guu1EKVQAAAJgG8EtjBvBL 4 | YwAAAAtzc2gtZWQyNTUxOQAAACBRf06YlDi/CVnLEDMTlxWH+OFojR1Y1d3rw7Guu1EKVQ 5 | AAAECHHCRxaxuDUzPhwiXZovjvMLYkLiSx+ho3b+9gavl031F/TpiUOL8JWcsQMxOXFYf4 6 | 4WiNHVjV3evDsa67UQpVAAAAE21hcmlhbm9AZW5kb3IubG9jYWwBAg== 7 | -----END NEBULA X25519 PRIVATE KEY----- 8 | -------------------------------------------------------------------------------- /pemutil/testdata/badnebula.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN NEBULA X25519 PUBLIC KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW 3 | QyNTUxOQAAACBRf06YlDi/CVnLEDMTlxWH+OFojR1Y1d3rw7Guu1EKVQAAAJgG8EtjBvBL 4 | YwAAAAtzc2gtZWQyNTUxOQAAACBRf06YlDi/CVnLEDMTlxWH+OFojR1Y1d3rw7Guu1EKVQ 5 | AAAECHHCRxaxuDUzPhwiXZovjvMLYkLiSx+ho3b+9gavl031F/TpiUOL8JWcsQMxOXFYf4 6 | 4WiNHVjV3evDsa67UQpVAAAAE21hcmlhbm9AZW5kb3IubG9jYWwBAg== 7 | -----END NEBULA X25519 PUBLIC KEY----- 8 | -------------------------------------------------------------------------------- /fipsutil/fipsutil_other.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.24 2 | 3 | package fipsutil 4 | 5 | // Enabled reports whether the cryptography libraries are operating in FIPS 6 | // 140-3 mode. 7 | // 8 | // On Go < 1.24 it will always return false. 9 | func Enabled() bool { 10 | return false 11 | } 12 | 13 | // Only reports whether the cryptography libraries are operating in FIPS 140-3 14 | // "only" mode. 15 | // 16 | // On Go < 1.24 it will always return false. 17 | func Only() bool { 18 | return false 19 | } 20 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.p521.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-EDE3-CBC,4C84DAF9EE70BBE8 4 | 5 | chCsynahRaHXIo23z8k20GrQjp5y7TKpFQQp8HPL+z9Cz9br7nNixTOE4n0kgbGi 6 | o4Cl4vvkduermhDtGEoxAYd1/QWR6kPqGOv8KdukwE/2AeD5DWLv14cMxVItjOMG 7 | 2R8BsLqdx+wT+5BPyDAiNRifNh+A0CTSIsjse2hhuUvuofh5VMJwXKOC4dZI+uUY 8 | 1gFOOX6IiGFu71UM2tdCjow27IJedJLH5p5qeq7nhIw4Ep/gDXE5mUF5zMi1syyi 9 | 9pEQzL0D2vNi+GgvLfYOgxjjcmeZ0pPNNViZmFol+ts= 10 | -----END EC PRIVATE KEY----- 11 | -------------------------------------------------------------------------------- /tpm/storage/tpmstore_test.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestFromContext(t *testing.T) { 11 | t.Parallel() 12 | 13 | exp := new(Dirstore) 14 | got := FromContext(NewContext(context.Background(), exp)) 15 | assert.Same(t, exp, got) 16 | } 17 | 18 | func TestFromContextPanics(t *testing.T) { 19 | t.Parallel() 20 | 21 | assert.Panics(t, func() { FromContext(context.Background()) }) 22 | } 23 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.p384.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED PRIVATE KEY----- 2 | MIIBEDBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIt+thawwnYS4CAggA 3 | MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECH9v1mUlx0D8BIHAvJG7iWo3OM5MFWZR 4 | SwjKrplMxIQL2zuMIkWQpvE+PuhscvJn4PaDE9LcrLoLLkjQINa9uxMFOZLt6fzH 5 | oRIG5SHb4ETUS1cLQ7iJayoghewuHa/WaRO2Gmf+oar45zYxADFzucWJOICRWY40 6 | 0eanbbRO/kYg0R0q2nr4QQT1EQBhbpuQa0y77RXGSQlduUpf4ybaSeBbnKE+kI+8 7 | L9WsEhkr/4zf4SmTFZXQllTxrgMOZ+EG2ggTyKxUWhfCgCv+ 8 | -----END ENCRYPTED PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /kms/tpmkms/no_tpmkms.go: -------------------------------------------------------------------------------- 1 | //go:build notpmkms 2 | 3 | package tpmkms 4 | 5 | import ( 6 | "context" 7 | "os" 8 | "path/filepath" 9 | 10 | "github.com/pkg/errors" 11 | "go.step.sm/crypto/kms/apiv1" 12 | ) 13 | 14 | func init() { 15 | apiv1.Register(apiv1.TPMKMS, func(ctx context.Context, opts apiv1.Options) (apiv1.KeyManager, error) { 16 | name := filepath.Base(os.Args[0]) 17 | return nil, errors.Errorf("unsupported KMS type 'tpmkms': %s is compiled without TPM KMS support", name) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /jose/testdata/rsa.pub.json: -------------------------------------------------------------------------------- 1 | { 2 | "use": "sig", 3 | "kty": "RSA", 4 | "kid": "CIsktcixZ5GyfkoWFyEV0tp5foASmBV4D-W7clYrCu8", 5 | "alg": "RS256", 6 | "n": "u1pASewznHZwedqjq85vEKRALbEBy57G4VWTrCY0wdFDThAtv3LwZaG1r9b79yDuqroz7PTT2vVQmzXwDQx78gix48XORLToUZrhcWcEhXxsYyTSJuD8groxHPNS_wTxrIH4ZKtFgJhdaOdSs9iFJpFEoq7DaVH89AWOEtAURek-KbkPci50IiQm-3Zwl9CBvDRs8528fGCthBFerm0kCXLw42oIeLJFC_iEHnR1NFzDuVZq6xjK1qp7vLoKMNUkkxmBFMduYOZth9Mf72i-l0VOZVt3gbHirR6RwXXH_K-NS6amGyB82w16g657p7rE3NXyEMMGXjOuObukMTd1jQ", 7 | "e": "AQAB" 8 | } -------------------------------------------------------------------------------- /kms/awskms/no_awskms.go: -------------------------------------------------------------------------------- 1 | //go:build noawskms 2 | 3 | package awskms 4 | 5 | import ( 6 | "context" 7 | "os" 8 | "path/filepath" 9 | 10 | "github.com/pkg/errors" 11 | "go.step.sm/crypto/kms/apiv1" 12 | ) 13 | 14 | func init() { 15 | apiv1.Register(apiv1.AmazonKMS, func(ctx context.Context, opts apiv1.Options) (apiv1.KeyManager, error) { 16 | name := filepath.Base(os.Args[0]) 17 | return nil, errors.Errorf("unsupported kms type 'awskms': %s is compiled without Amazon KMS support", name) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /kms/softkms/testdata/rsa.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn2Oh7/uWB5RH40la1a43 3 | IRaLZ8EnJVw5DCKE3BUre8xflVY2wTIS7XHcY0fEGprtq7hzFKors9AIGGn2yGrf 4 | bZX2I+1g+RtQ6cLL6koeLuhRDqCuae0lZPulWc5ixBmM9mpl4ARRcpQFldxFRhis 5 | xUaHMx8VqdZjFSDc5CJHYYK1n2G5DyuzJCk6yOfyMpwxizZJF4IUyqV7zKmZv1z9 6 | /Xd8X0ag7jRdaTBpupJ1WLaq7LlvyB4nr47JXXkLFbRIL1F/gTcPtg0tdEZiKnxs 7 | VLKwOs3VjhEorUwhmVxr4NnNX/0tuOY1FJ0mx5jKLAevqLVwK2JIg/f3h7JcNxDy 8 | tQIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /x509util/testdata/rawSubject.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIBIjCBygIBADBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW 3 | MBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEdMBsGA1UECgwUU21hbGxzdGVwIExhYnMs 4 | IEluYy4xDTALBgNVBAMMBFRlc3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATG 5 | NLZtzv5dcl2Nz66XBV+tq5jKCH9WGPlsuBEq48NNUb1LzecjaVTZsEwe+ZpQbnzk 6 | wTdYXFI68HbovxWc9fDxoAAwCgYIKoZIzj0EAwIDRwAwRAIgODOqVqdeZzSwZOFB 7 | VZuSLoMVvCVoiFng8/2hXfJWJi4CIBNHEt9batonI4Z6Z0kij/qNTeTTWFd5yawX 8 | 2DP2+6EP 9 | -----END CERTIFICATE REQUEST----- -------------------------------------------------------------------------------- /kms/capi/no_capi.go: -------------------------------------------------------------------------------- 1 | //go:build !windows || nocapi 2 | 3 | package cloudkms 4 | 5 | import ( 6 | "context" 7 | "os" 8 | "path/filepath" 9 | 10 | "github.com/pkg/errors" 11 | "go.step.sm/crypto/kms/apiv1" 12 | ) 13 | 14 | func init() { 15 | apiv1.Register(apiv1.CAPIKMS, func(context.Context, apiv1.Options) (apiv1.KeyManager, error) { 16 | name := filepath.Base(os.Args[0]) 17 | return nil, errors.Errorf("unsupported kms type 'capi': %s is compiled without Microsoft CryptoAPI support", name) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /kms/tpmkms/errors.go: -------------------------------------------------------------------------------- 1 | package tpmkms 2 | 3 | import "errors" 4 | 5 | var ( 6 | ErrIdentityCertificateUnavailable = errors.New("AK certificate not available") 7 | ErrIdentityCertificateNotYetValid = errors.New("AK certificate not yet valid") 8 | ErrIdentityCertificateExpired = errors.New("AK certificate has expired") 9 | ErrIdentityCertificateIsExpiring = errors.New("AK certificate will expire soon") 10 | ErrIdentityCertificateInvalid = errors.New("AK certificate does not contain valid identity") 11 | ) 12 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.ed25519.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABC9Pd+JT/ 3 | 54ZI1CUG/rb3D1AAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIFF/TpiUOL8JWcsQ 4 | MxOXFYf44WiNHVjV3evDsa67UQpVAAAAoL35/C3KKjC+Z6fVLWlvDqYnhyNdic4H7O2XGj 5 | yg9h9BBQGKAK5MdNkE9xtSffw9v6wIJrLQTyoqvE2dyaTcqeW+vn6iDypF4f9gzrwdZz6j 6 | YD8Y392OcNwZF4JcoT3nvrkQ2sCRHDbQbYID+N80ml5VbijvRd2b6YiFJMZO2nwUtPqVCt 7 | RYRBsy1/0m6740+SRTztB4DqkNdZO41zH25WM= 8 | -----END OPENSSH PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.rsa2048.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4uI83MBkkLHDoHmLNrd7 3 | ooIbzm+ZeX6jSB2HiwpmA7PRjpgtxBD2fjt8QZ1qXUi9GkSlajiomK5Q64+Dg+6C 4 | Jp97Lkm4EybwQvHJqbzA+pHFCrNLDVBea2O/kRBMzdSr7aI0p8gwruVStwADtNYK 5 | 4nrd45X08SE3Hl5iB4tMBMrOvBugv5fTaII5ZMQ6AzqqWwk/pTP/dfjKfGPO+rN7 6 | g3PQ4/B+yXjDWfAld9dFk7Wl53PorC7oqcU4MZMyGImXgi58V7lx+XhRqvcRUx1y 7 | 2CBUJu6aHgvBERsf+vXSf5q1HiIMUFYMhn+duLoTRBZj3JPDE36J6SOIHDg8xoQD 8 | nwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /tlsutil/utils.go: -------------------------------------------------------------------------------- 1 | package tlsutil 2 | 3 | import ( 4 | "net" 5 | 6 | "go.step.sm/crypto/x509util" 7 | ) 8 | 9 | // SanitizeName converts the given domain to its ASCII form. 10 | var SanitizeName = x509util.SanitizeName 11 | 12 | // SanitizeHost returns the ASCII form of the host part in a host:port address. 13 | func SanitizeHost(host string) (string, error) { 14 | if h, _, err := net.SplitHostPort(host); err == nil { 15 | return x509util.SanitizeName(h) 16 | } 17 | return x509util.SanitizeName(host) 18 | } 19 | -------------------------------------------------------------------------------- /kms/azurekms/no_azurekms.go: -------------------------------------------------------------------------------- 1 | //go:build noazurekms 2 | 3 | package azurekms 4 | 5 | import ( 6 | "context" 7 | "os" 8 | "path/filepath" 9 | 10 | "github.com/pkg/errors" 11 | "go.step.sm/crypto/kms/apiv1" 12 | ) 13 | 14 | func init() { 15 | apiv1.Register(apiv1.AzureKMS, func(ctx context.Context, opts apiv1.Options) (apiv1.KeyManager, error) { 16 | name := filepath.Base(os.Args[0]) 17 | return nil, errors.Errorf("unsupported kms type 'azurekms': %s is compiled without Azure KMS support", name) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.rsa2048.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzW1NxCQUYTP5q7eXumLP 3 | FbPrNEKTcuLY+Gj8nMkr7Xb6egwZsCKcw8Mor/WHsuIpe8hXV3XZbiGQC0ON7PUk 4 | p7LNj+N0+5xndZSYr3QUYsjcwCo3ZaS2rfNLq6S3HHBKflhmzY8j9g1ieGYJVmeH 5 | a2wZ4v2p+raTAvE5B4m4X12pms0cA6rgZzmuluBpHe7D/I8H8Gv31zI3227mi5uD 6 | w1wupZC0EzUHWRDd5xBYL0HDrDrjlGzDqmhj9XqVf7FbDUoFqpUt6C+j5qDYjXvp 7 | wYkgAq2KKZQQ/FsdXRupPmyPlhFBfSHGwqM6WJLaMTVxMIOMrFYU2ePlqU4Ydm81 8 | nwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation Request 3 | about: Request documentation for a feature 4 | title: '' 5 | labels: docs, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | 15 | -------------------------------------------------------------------------------- /kms/cloudkms/no_cloudkms.go: -------------------------------------------------------------------------------- 1 | //go:build nocloudkms 2 | 3 | package cloudkms 4 | 5 | import ( 6 | "context" 7 | "os" 8 | "path/filepath" 9 | 10 | "github.com/pkg/errors" 11 | "go.step.sm/crypto/kms/apiv1" 12 | ) 13 | 14 | func init() { 15 | apiv1.Register(apiv1.CloudKMS, func(ctx context.Context, opts apiv1.Options) (apiv1.KeyManager, error) { 16 | name := filepath.Base(os.Args[0]) 17 | return nil, errors.Errorf("unsupported kms type 'cloudkms': %s is compiled without Google Cloud Key Management support", name) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /kms/yubikey/yubikey_no_cgo.go: -------------------------------------------------------------------------------- 1 | //go:build !cgo || noyubikey 2 | 3 | package yubikey 4 | 5 | import ( 6 | "context" 7 | "os" 8 | "path/filepath" 9 | 10 | "github.com/pkg/errors" 11 | 12 | "go.step.sm/crypto/kms/apiv1" 13 | ) 14 | 15 | func init() { 16 | apiv1.Register(apiv1.YubiKey, func(ctx context.Context, opts apiv1.Options) (apiv1.KeyManager, error) { 17 | name := filepath.Base(os.Args[0]) 18 | return nil, errors.Errorf("unsupported kms type 'yubikey': %s is compiled without cgo or YubiKey support", name) 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /tpm/errors.go: -------------------------------------------------------------------------------- 1 | package tpm 2 | 3 | import ( 4 | "errors" 5 | 6 | "go.step.sm/crypto/tpm/storage" 7 | ) 8 | 9 | // ErrNotFound is returned when a Key or AK cannot be found 10 | var ErrNotFound = errors.New("not found") 11 | 12 | // ErrExists is returned when a Key or AK already exists 13 | var ErrExists = errors.New("already exists") 14 | 15 | // ErrNoStorageConfigured is returned when a TPM operation is 16 | // performed that requires a storage to have been configured 17 | var ErrNoStorageConfigured = storage.ErrNoStorageConfigured 18 | -------------------------------------------------------------------------------- /kms/sshagentkms/no_sshagentkms.go: -------------------------------------------------------------------------------- 1 | //go:build nosshagentkms 2 | 3 | package sshagentkms 4 | 5 | import ( 6 | "context" 7 | "os" 8 | "path/filepath" 9 | 10 | "github.com/pkg/errors" 11 | "go.step.sm/crypto/kms/apiv1" 12 | ) 13 | 14 | func init() { 15 | apiv1.Register(apiv1.SSHAgentKMS, func(ctx context.Context, opts apiv1.Options) (apiv1.KeyManager, error) { 16 | name := filepath.Base(os.Args[0]) 17 | return nil, errors.Errorf("unsupported kms type 'sshagentkms': %s is compiled without SSH Agent KMS support", name) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.p256.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS 3 | 1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQSN5Ld/DFy8LJK0yrWg+Ryhq4/ifHry 4 | QyCQeT4UXSB+UGdRct7kWA0hARbTaSCh+8U/Gs5O+IkDNoTKVsgxKUMQAAAAsO3C7nPtwu 5 | 5zAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI3kt38MXLwskrTK 6 | taD5HKGrj+J8evJDIJB5PhRdIH5QZ1Fy3uRYDSEBFtNpIKH7xT8azk74iQM2hMpWyDEpQx 7 | AAAAAhAIHB48R+goZaiXndfYTrwk4BT1+MeLPC2/dwe0J5d1QDAAAAE21hcmlhbm9AZW5k 8 | b3IubG9jYWwBAgME 9 | -----END OPENSSH PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /tpm/internal/socket/socket_others.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | 3 | package socket 4 | 5 | import ( 6 | "io" 7 | "os" 8 | 9 | "github.com/google/go-tpm/tpmutil" 10 | ) 11 | 12 | func newSocket(path string) (io.ReadWriteCloser, error) { 13 | if path == "" { 14 | return nil, ErrNotAvailable 15 | } 16 | fi, err := os.Stat(path) 17 | if err != nil { // TODO(hs): handle specific errors here? 18 | return nil, err 19 | } 20 | if fi.Mode()&os.ModeSocket != 0 { 21 | return tpmutil.NewEmulatorReadWriteCloser(path), nil 22 | } 23 | return nil, ErrNotAvailable 24 | } 25 | -------------------------------------------------------------------------------- /tpm/storage/errors.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import "errors" 4 | 5 | // TODO: provide key/ak name in the error? 6 | 7 | // ErrNotFound is returned when a Key or AK cannot be found in storage 8 | var ErrNotFound = errors.New("not found") 9 | 10 | // ErrExists is returned when a Key or AK already exists in storage 11 | var ErrExists = errors.New("already exists") 12 | 13 | // ErrNoStorageConfigured is returned when a TPM operation is 14 | // performed that requires a storage to have been configured 15 | var ErrNoStorageConfigured = errors.New("no storage configured") 16 | -------------------------------------------------------------------------------- /tpm/internal/socket/socket.go: -------------------------------------------------------------------------------- 1 | package socket 2 | 3 | import ( 4 | "errors" 5 | "io" 6 | ) 7 | 8 | var ( 9 | ErrNotAvailable = errors.New("socket not available") 10 | ErrNotSupported = errors.New("connecting to a TPM using a UNIX socket is not supported on Windows") 11 | ) 12 | 13 | func New(path string) (io.ReadWriteCloser, error) { 14 | return newSocket(path) 15 | } 16 | 17 | type CommandChannelWithoutMeasurementLog struct { 18 | io.ReadWriteCloser 19 | } 20 | 21 | func (c *CommandChannelWithoutMeasurementLog) MeasurementLog() ([]byte, error) { 22 | return nil, nil 23 | } 24 | -------------------------------------------------------------------------------- /x509util/testdata/ed25519.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBWzCCAQ2gAwIBAgIUDIPYISuCyyOYI2Pi95eKQ1vzvZIwBQYDK2VwMCMxITAf 3 | BgNVBAMMGEVkMjU1MTkgdGVzdCBjZXJ0aWZpY2F0ZTAeFw0xOTA1MDYxNzI3MTZa 4 | Fw0xOTA2MDUxNzI3MTZaMCMxITAfBgNVBAMMGEVkMjU1MTkgdGVzdCBjZXJ0aWZp 5 | Y2F0ZTAqMAUGAytlcAMhADYpxWwNTxRsgdD/ddNqcF9pzQ9NZtXamH6CSYmjijz6 6 | o1MwUTAdBgNVHQ4EFgQUCTs6nUop2JX/aL57Q1Ry4K2i464wHwYDVR0jBBgwFoAU 7 | CTs6nUop2JX/aL57Q1Ry4K2i464wDwYDVR0TAQH/BAUwAwEB/zAFBgMrZXADQQBT 8 | pVgcLDsqnqydTqUdX11tprUI3hKC85cgrvrYmPQagzJrkfUkHcQgfyziTdoTO21U 9 | GtKoKNxgudT0eEs8HJEA 10 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /jose/testdata/host-key.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDDA6iolHi1F7d/tZcoSm5RPjznn+Td44+VtUYWWBL0SQ1rVuyzNXq1T7hHDRxxNf92mCHHeHhRZYPKmh63GZiJSWkVmqn8By4qyQB5EpuE8H+5czBNtNpk1GG+q7u5eOBSIh9F4Zgzb/h7+BwGHU4srRhUuOG/u4DmGsEONVkpnD1aljgIz9vWRauM6/bJ20M/TiNL42L6YEclDoNoV9m1kkFM6Oib+6XFgo9Ihd5E41Y7uAPFe5kmTaHHw+dmjQGTVYqF1rOiope7dyh1EIkzDWIoOHOlpnKYTaPICkoKuVXj/NfHE0vsv0ltl/hamy0D4GQx8n0X/Wi48yNnYZke6Xc6jpXIt3YI2M8vUtYI5mR5wm7nQCIMH1INbXxKakrAIqtaEq5+OIstNO1agX5FwMwjfQha/fpUnhbw+Btxc/QuNnvI/wM+EVbm44YZuHEUoN9H+9LigAuiRzpqtLbPrBhssxNTcvpcbiOaYFkpj/JNbvn7ZCmQb/sF/GkXyrU= mariano@overlook.attlocal.net 2 | -------------------------------------------------------------------------------- /jose/testdata/ssh-ca.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCwNqb7lWC0L3fSK/zTZMBAElBLhSZutaXR8AoufxA8tmy/JU5i239sEv7kYDmR/HxEMBpOOaVL8xrxRq1hRFTJij6Hw+wiDW9l9+5joCtS1h4ZuRbsr/h1fZd7SCXDNNgVFsMgqvpymjhgB62IBuaZ+r+HmJUr1RZ8IpnNFax/D7KA98f3ssGuMgPCDOrKWdNZWaUV9yL01JXUdbiaputmUFxfg2NgAfKpeQYwNjsPYGCcR7n3Gd9R6bLEBRhirvrMCzRMFNFSEaI52W8ZYACr6EKXMRY/v7bnX5AjAo7DqXOr97uoWosnMhbWVKhcT9UaEqQArNAPmjj3yiqS0+gjqVqHPaF+qNv2tujf7jCEbmBz8oO89Kk1/U6csA/4nTMg8RKlaJU7ymke0FDfcGhs+Wji9NqOlIgitWCZJ/VPVj4kV+EEPd4JumYk4WNqtaR83pWTREp83GsB7M+rWSfxXzYyOEFPHqFdtIvKqe2wyVO3JzJitVUhMfiYbFQS19M= mariano@overlook.attlocal.net 2 | -------------------------------------------------------------------------------- /pemutil/testdata/ca2.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBYjCCAQigAwIBAgIRAPbtfP0mbPikhw3/xm4ZOfAwCgYIKoZIzj0EAwIwDzEN 3 | MAsGA1UEAxMEcm9vdDAeFw0yMzA0MTExNTMwMTJaFw0zMzA0MDgxNTMwMTJaMA8x 4 | DTALBgNVBAMTBHJvb3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARrIw/HltUP 5 | IJijX+enYDM/ki80qz40E9JxbQTqlW/P/C/19Vj6tqWat/+YzdxVxFqf9AamBoZ6 6 | Gjy5+VqxifcEo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIB 7 | ATAdBgNVHQ4EFgQUZX1K+aVs2nulegBQ2wgv3wkXTmAwCgYIKoZIzj0EAwIDSAAw 8 | RQIgOj+jv1dpCLWDmGbGjfwFO9ZL+NL+n2SI+qrA40ogLj8CIQDKX6EOwubb7xXj 9 | wJRCXLDKXYC/OUpLCT2FJsSTupRB9A== 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.p521.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED PRIVATE KEY----- 2 | MIIBSzBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIKPk6W5eAKYgCAggA 3 | MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECDwwqYU8+d1WBIH4Q92kQSL2HaDj 4 | OR/6zqkkAtLs3/xGzUwHTw3SIzyv/W8Ob777N4pYVbIjoN9MrcbZ7Qn5S2bD8iua 5 | WU0cszSAqJ0nsNeDtUNAqV4vnYJegUDEEWr7UDGh0WCofCRec9ZxCuJLJwsc8Men 6 | XrfFxvym6y6+arjqLBKTUDRzpc+qYOFokvQeVRHOkN0XsgYj2SLHoiTsyx1vLlkV 7 | dQ9E8+z4Hchi1MrB2oDmqem4h+YUVhoc1KrXntEKb2u5UYMxLGKAA0itC4k/GfuN 8 | NUpO9jx+F2g+/kmHqfSTOzCmI3ptTdVouXwbez/isIW0KsNNgodnN+HdoYdmiU0= 9 | -----END ENCRYPTED PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /nssdb/testdata/root-ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBaDCCAQ2gAwIBAgIQOIvltk7+PagyWqMTC3o4GDAKBggqhkjOPQQDAjASMRAw 3 | DgYDVQQDEwdyb290LWNhMB4XDTI1MDEyODE5NTU0M1oXDTM1MDEyNjE5NTU0M1ow 4 | EjEQMA4GA1UEAxMHcm9vdC1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABIkJ 5 | a/NBM+jGujZ5ahaxAHmpLMP1n0+ujOQ5EZOBzNR7lLxVR0MW+QSgiGA2fo72aQR1 6 | 7/H3/CcNqG0RjiCTsDKjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG 7 | AQH/AgEBMB0GA1UdDgQWBBQ8Y6o937i22hHa1MIn65WDiRKxEDAKBggqhkjOPQQD 8 | AgNJADBGAiEA4C7lKgkbcGT6z+GxXhyyWtg7Mwxi5dUvwCStUpal9rwCIQCebftK 9 | j4+1sv+plLMMORaMXzcMFSksXavHznXmCybbpw== 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /tpm/names_test.go: -------------------------------------------------------------------------------- 1 | package tpm 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_processName(t *testing.T) { 10 | name := "name1" 11 | name, err := processName(name) 12 | require.NoError(t, err) 13 | require.Equal(t, "name1", name) 14 | 15 | name, err = processName("") 16 | require.NoError(t, err) 17 | require.Len(t, name, 10) 18 | } 19 | 20 | func Test_prefixAK(t *testing.T) { 21 | require.Equal(t, "ak-name", prefixAK("name")) 22 | } 23 | 24 | func Test_prefixKey(t *testing.T) { 25 | require.Equal(t, "app-name", prefixKey("name")) 26 | } 27 | -------------------------------------------------------------------------------- /jose/testdata/okp.enc.priv.json: -------------------------------------------------------------------------------- 1 | { 2 | "protected": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMjU2R0NNIiwicDJjIjoxMDAwMDAsInAycyI6ImxUMTJjQ29FUEdYWXV2V0JqNHFZZ1EifQ", 3 | "encrypted_key": "_029j7ZniKPgkRbVzwjgPPUtCdQacFMLB-k9p-INRksow1a1-wHGTA", 4 | "iv": "WyrGXSosdyfBNWMW", 5 | "ciphertext": "5DNleiF85yWEDZFXQj-XSZ6JlepRei3k8V15oMecxXB_XnT7CL5ufZ9e884P3RGinA0gl_x3ViYFdFJthqJ79aHw7VtRVfe3Ar3USUcttPHxZmtrXd2yGWn1Osw3jyADeuXXaSED2EWNHiXUsjC3IGoGMWbMtKW7KuckZudkanSzYFRvuCPdLrDrvnugoMZX-he-NM1181OiOvZjtA-3TPKVLk7tuSnTOcqQAvpKoAy18NS6orslnVfFMz6tyYq3RvD8lbc-RN3o6op4Cphz", 6 | "tag": "rCmSF2Ts2Q61KubS_Bmceg" 7 | } -------------------------------------------------------------------------------- /internal/emoji/emoji_test.go: -------------------------------------------------------------------------------- 1 | package emoji 2 | 3 | import "testing" 4 | 5 | func TestEmoji(t *testing.T) { 6 | type args struct { 7 | input []byte 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want string 13 | }{ 14 | {"ok", args{[]byte{0x00, 0x10, 0x50, 0xAA, 0xFF}}, "👍🛁🇫🇷👛💤"}, 15 | {"empty", args{[]byte{}}, ""}, 16 | {"nil", args{nil}, ""}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := Emoji(tt.args.input); got != tt.want { 21 | t.Errorf("Emoji() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.p256.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDVMVSBp4 3 | T/VwzGf55k3unNAAAAEAAAAAEAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlz 4 | dHAyNTYAAABBBI3kt38MXLwskrTKtaD5HKGrj+J8evJDIJB5PhRdIH5QZ1Fy3uRYDSEBFt 5 | NpIKH7xT8azk74iQM2hMpWyDEpQxAAAACwjNTJDRz89Ci7Is9ngcxzZGQbJV+hFH4KA/7f 6 | YqzB+/HTCQh9F+JOcmQmiOUNJCAexzrl9o1Z3342WYllL4U7yxc7jz5a0MdCd/Bzx8TbJS 7 | JjO54BX61cpejSaBJiVDmo4kKyYY34a4NOoc4eoa74r8vN/hqOvG4J8nzBTWPbZIjEfGRA 8 | GKpoNh2nFkqFYkiciXTNldokFQ/mFV+lbGtX8VoJCRbcLgk+wtzLfIYpZ2Y= 9 | -----END OPENSSH PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /x509util/testdata/capath2/root1.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBdTCCARygAwIBAgIRAMzIwp8pYDKH01yvNcwKLqYwCgYIKoZIzj0EAwIwGTEX 3 | MBUGA1UEAxMOU21hbGxzdGVwIENBIDEwHhcNMjEwNDE0MDEyNzMwWhcNMzEwNDEy 4 | MDEyNzMwWjAZMRcwFQYDVQQDEw5TbWFsbHN0ZXAgQ0EgMTBZMBMGByqGSM49AgEG 5 | CCqGSM49AwEHA0IABPKwI/NGpH5uWYH9KYrusC3aszBIxin+mDFSt7sJiPjfkHps 6 | l8HPUWrUvjz0BuHm0ic52zCHwftQc1EXFDuDxpajRTBDMA4GA1UdDwEB/wQEAwIB 7 | BjASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBTxlV+DRZS5m5HrFGf83OsG 8 | W4SYNzAKBggqhkjOPQQDAgNHADBEAiBdVZTcpwwZpfgmU6jqpO8Amn1O3ZZSHXog 9 | XWDjTaH/4gIgTaGEuNVMXoMQl/nr8lEcQtaP/p+0woHKL9JGr13ZYNI= 10 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /x509util/testdata/capath2/root2.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBdjCCARygAwIBAgIRAMhq6mlSxCy4ZfXyvlOabZEwCgYIKoZIzj0EAwIwGTEX 3 | MBUGA1UEAxMOU21hbGxzdGVwIENBIDIwHhcNMjEwNDE0MDEyNzM5WhcNMzEwNDEy 4 | MDEyNzM5WjAZMRcwFQYDVQQDEw5TbWFsbHN0ZXAgQ0EgMjBZMBMGByqGSM49AgEG 5 | CCqGSM49AwEHA0IABDPFYafdCLBSLtjXZev0PEHJpRyYhLiFUjOGx/Dxbie0LGmU 6 | fWlU8AIh7e9jjvl+ugdhco3CoWEUoBCuD9S99DujRTBDMA4GA1UdDwEB/wQEAwIB 7 | BjASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBQj++HJHgFcVIvah8WOTvMd 8 | UboxGDAKBggqhkjOPQQDAgNIADBFAiBeMmKo4n3LvQCgGF609rH/fjJbGI00ZrrS 9 | Pe9qXRrxWwIhAKBurnttPIYbOzidmrFA8fBF4w24lu0WmDOr5Cz8IfP9 10 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /jose/testdata/p256.enc.priv.json: -------------------------------------------------------------------------------- 1 | { 2 | "protected": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6InFMYmNET3Yxczc3TlRGcnlKVUUtbmcifQ", 3 | "encrypted_key": "hY7Q7izJs6V1XvZI1l0RXJZ72XGg4anK", 4 | "iv": "gZb91xunOTgPqVF2", 5 | "ciphertext": "N-J28rcs385tnLyM32ynQpeRSn3nkcaaSoO9o0H7dxrsLJ7nV53DKGprDjAWhVWonbf3BxSIj1K5CUgMP8GPqUvJnZldgYILzvTRbGSPjYrGd5m2kUCAxIuRFbHNA35Lv02rfbNH9jvfdRvKhWvgunHS-a8vJCBCyk-Bd16Cp05G7tXp_EeVQXpUvNtQLd0v9NhWQ-tBeU86E3peCaJ97qipu7Xf23Axbng5azFzCGbSbmj4e0HN58HmHcpMDI8TgXrQ5-vDsRIE8U8YKJGqw5OVlRRM_gusQyZTBRHDFb5xkyFbD1SMpCRDdFTT0qS0k5vcH8ijpjSIs3K-sFo", 6 | "tag": "WG-RibO1NdWRaqHRHUwl3A" 7 | } -------------------------------------------------------------------------------- /tpm/attestation/testdata/roots.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBhzCCASygAwIBAgIRANJiwPnM38wWznkJGOcIyIYwCgYIKoZIzj0EAwIwITEf 3 | MB0GA1UEAxMWU21hbGxzdGVwIFRlc3QgUm9vdCBDQTAeFw0xODA5MjcxODE4MDla 4 | Fw0yODA5MjQxODE4MDlaMCExHzAdBgNVBAMTFlNtYWxsc3RlcCBUZXN0IFJvb3Qg 5 | Q0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS15w7dx9zPjCnQ7+RlRkvUXQJN 6 | Fjk5Hg5K9nCoiiNQQhcQMw63/pXQxHNsugiMshcN59XJC8195KJPm25nXN8co0Uw 7 | QzAOBgNVHQ8BAf8EBAMCAaYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQU 8 | B2BAXUSPZbFjnY6VzbApV48Tn3owCgYIKoZIzj0EAwIDSQAwRgIhAJRTVmc2xW8c 9 | ESx4oIp2d/OX9KBZzpcNi9fHnnJCS0FXAiEA7OpFb2+b8KBzg1c02x21PS7pHoET 10 | /A8LXNH4M06A7vE= 11 | -----END CERTIFICATE----- 12 | -------------------------------------------------------------------------------- /sshutil/certificate_request.go: -------------------------------------------------------------------------------- 1 | package sshutil 2 | 3 | import "golang.org/x/crypto/ssh" 4 | 5 | // CertificateRequest simulates a certificate request for SSH. SSH does not have 6 | // a concept of certificate requests, but the CA accepts the key and some other 7 | // parameters in the requests that are part of the certificate. This struct will 8 | // hold these parameters. 9 | // 10 | // CertificateRequest object will be used in the templates to set parameters 11 | // passed with the API instead of the validated ones. 12 | type CertificateRequest struct { 13 | Key ssh.PublicKey 14 | Type string 15 | KeyID string 16 | Principals []string 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | tags-ignore: 6 | - 'v*' 7 | branches: 8 | - "master" 9 | pull_request: 10 | workflow_call: 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | ci: 18 | uses: smallstep/workflows/.github/workflows/goCI.yml@main 19 | with: 20 | only-latest-golang: false 21 | os-dependencies: 'libpcsclite-dev' 22 | run-build: false 23 | run-codeql: true 24 | codeql-build-cmd: 'go build ./...' 25 | test-command: 'V=1 make test' 26 | secrets: inherit 27 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | 6 | #### Name of feature: 7 | 8 | #### Pain or issue this feature alleviates: 9 | 10 | #### Why is this important to the project (if not answered above): 11 | 12 | #### Is there documentation on how to use this feature? If so, where? 13 | 14 | #### In what environments or workflows is this feature supported? 15 | 16 | #### In what environments or workflows is this feature explicitly NOT supported (if any)? 17 | 18 | #### Supporting links/other PRs/issues: 19 | 20 | 💔Thank you! 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "gomod" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | - package-ecosystem: "github-actions" 13 | directory: "/" 14 | schedule: 15 | interval: "weekly" 16 | -------------------------------------------------------------------------------- /keyutil/testdata/rsa.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAoifEXKTF5rOvbTXbXXFD 3 | DdXEE7iwI6S6cEf5N8pdCgbk+RdPYBwK0Y6BZU27md22ZJZmH9uts/6mx6Ajty/q 4 | YsngMEyLNhVIvu7H2KfKqed4vTRJ13/ID9HNB9eMCPnG+NUu1U/CEPk0p+/lhKM1 5 | mQyyS6at6wmI1Wn7jiJQeCoS9fQNl5OsevnAU0304jwQHcuFhBAQTwxmLr2iG3+8 6 | f8VHL14YlmcYXl4RWFEvgsoe8KGdQRUHaCLpCQAaO2OmEEYZGO+4UWRMS/kKUrDS 7 | RHiX9oGUDnweP2YJ4VAymOkrWpQMJeXJi+pp8fWyl/D+SWCPT/+O3IFitb/ff1QA 8 | xw81+Q2ascCmZ61nq3bvrKcGqjjMDYxrXut+LxxHnZqeTCmTShMQJTRnrzMP5le9 9 | 4FN6h6zpI6jcr6friMzec3B87z9XtFN7xlNLCOOi7LkzikvKta4flDUCEnPfZFes 10 | OOQMfkG1W8PFyWzZtEyWPneVhttncsoZsM7gM1QsGw+lAgMBAAE= 11 | -----END PUBLIC KEY----- 12 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.p384.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAiAAAABNlY2RzYS 3 | 1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQTZb2VzEPs2NN/i1qHddKTVfwoIq3Tf 4 | PeQ/kcWBvuCVJfIygvpm9MeusawEPuLSEXwiNDew+YHZ9xHIvFjCmZsLuEOzuh9t9KotwM 5 | 57H+7N+RDFzhM2j8hAaOuT5XDLKfUAAADgn/Sny5/0p8sAAAATZWNkc2Etc2hhMi1uaXN0 6 | cDM4NAAAAAhuaXN0cDM4NAAAAGEE2W9lcxD7NjTf4tah3XSk1X8KCKt03z3kP5HFgb7glS 7 | XyMoL6ZvTHrrGsBD7i0hF8IjQ3sPmB2fcRyLxYwpmbC7hDs7ofbfSqLcDOex/uzfkQxc4T 8 | No/IQGjrk+Vwyyn1AAAAMQDg0hwGKB/9Eq+e2FeTspi8QHW5xTD6prqsHDFx4cKk0ccgFV 9 | 61dhFhD/8SEbYlHzEAAAATbWFyaWFub0BlbmRvci5sb2NhbAECAwQ= 10 | -----END OPENSSH PRIVATE KEY----- 11 | -------------------------------------------------------------------------------- /tpm/tss2/simulator_test.go: -------------------------------------------------------------------------------- 1 | //go:build tpmsimulator 2 | 3 | package tss2 4 | 5 | import ( 6 | "crypto/rand" 7 | "encoding/hex" 8 | "io" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/require" 12 | "go.step.sm/crypto/tpm/simulator" 13 | ) 14 | 15 | var seed string 16 | 17 | func init() { 18 | b := make([]byte, 8) 19 | if _, err := io.ReadFull(rand.Reader, b); err != nil { 20 | panic(err) 21 | } 22 | seed = hex.EncodeToString(b) 23 | } 24 | 25 | func openTPM(t *testing.T) io.ReadWriteCloser { 26 | t.Helper() 27 | 28 | sim, err := simulator.New(simulator.WithSeed(seed)) 29 | require.NoError(t, err) 30 | require.NoError(t, sim.Open()) 31 | return sim 32 | } 33 | -------------------------------------------------------------------------------- /kms/cloudkms/testdata/rsapub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsrAcFrWhJLBEjgrbt962 3 | GJULrg/FZQ+MB+KQJi+mv2VoVq6Rp7g+H7EyAi8b9a9cf1X4vFLjEpEFFhhji0e7 4 | BZIIeE96rOHdq9Rf8MEyy8YcqKe1eTeQhOTsyD7pletjyNUOC/DexN2saS7N80uj 5 | vEKpEprDNf+XCTrQqDTlBO4LWNPu7e8xjm+Wvnb9P8Kizln4Z8cfRjxRUwpYRgjh 6 | YdhHegT2a6lZodthh+iw83P5WlxJBuDNiKk+E0kIePDQLg2irjNr/gjo2O13yUNn 7 | +ZdtdRjSjOAlrW/n1rxs6TIMYv/qEGinnj2j47cTAQqDzNdw8GwbzJcA0iajNvQj 8 | Ge4RoO0p4jPiD+9H0qfraNf3e1VQcIUoRoohlwrisBJCUrpSiTKbp9orVCrY9ZvA 9 | uQyUpiLnsN7//+tQUDEX3Tw4rpl0oY48TYMqzzs9mNd3lnkJnkEecM0m+dP/8wEb 10 | Np5KtEnqmuW3UNWnvzxB9HGVIYt35fjGCHHIZl9PbnqbAgMBAAE= 11 | -----END PUBLIC KEY----- 12 | -------------------------------------------------------------------------------- /nssdb/testdata/leaf.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBpTCCAUqgAwIBAgIRAPU9WqhWXvsIj6kxb05tFwEwCgYIKoZIzj0EAwIwEjEQ 3 | MA4GA1UEAxMHcm9vdC1jYTAeFw0yNTAxMjgxOTU1NDNaFw0yNTAxMjkxOTU1NDNa 4 | MA8xDTALBgNVBAMTBGxlYWYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASF+k43 5 | +7tHeUxVwq0isAbT+Ne+8qrpMCed8hrn9T/+fZOvSE6raUoeAf+QE0pm+98sjS2+ 6 | 29nn65pJN0qHoRfHo4GDMIGAMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggr 7 | BgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0OBBYEFFhbMxRm1HX1W2VN6vvWCbWPtbNi 8 | MB8GA1UdIwQYMBaAFDxjqj3fuLbaEdrUwifrlYOJErEQMA8GA1UdEQQIMAaCBGxl 9 | YWYwCgYIKoZIzj0EAwIDSQAwRgIhAKaJb+q5vkNNbnx7o2M+C4xJAQYBnwxXa6LQ 10 | kDyOe3I7AiEAjmiRmAz6R2n+/JJGiWfjTnkOcS1A9CDjnZmDRKOq2lY= 11 | -----END CERTIFICATE----- 12 | -------------------------------------------------------------------------------- /tpm/storage/blackhole.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import "context" 4 | 5 | // BlackHole returns a [FeedthroughStore] without a backing 6 | // storage, effectively resulting in no persistence. Note 7 | // that some operations do require persistence, in which 8 | // case [ErrNoStorageConfigured] will be returned by the 9 | // [FeedthroughStore]. 10 | func BlackHole() TPMStore { 11 | return NewFeedthroughStore(nil) 12 | } 13 | 14 | // BlackholeContext adds a new BlackHole storage to the context. 15 | func BlackHoleContext(ctx context.Context) context.Context { 16 | if ctx == nil { 17 | ctx = context.Background() 18 | } 19 | ctx = NewContext(ctx, BlackHole()) 20 | return ctx 21 | } 22 | -------------------------------------------------------------------------------- /kms/mackms/mackms_other.go: -------------------------------------------------------------------------------- 1 | //go:build !cgo || !darwin || nomackms 2 | 3 | package mackms 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "os" 9 | "path/filepath" 10 | "runtime" 11 | 12 | "go.step.sm/crypto/kms/apiv1" 13 | ) 14 | 15 | func init() { 16 | apiv1.Register(apiv1.MacKMS, func(context.Context, apiv1.Options) (apiv1.KeyManager, error) { 17 | name := filepath.Base(os.Args[0]) 18 | switch runtime.GOOS { 19 | case "darwin": 20 | return nil, fmt.Errorf("unsupported kms type 'mackms': %q is compiled without cgo or mackms support", name) 21 | default: 22 | return nil, fmt.Errorf("unsupported kms type 'mackms': %q is not running on a macOS", name) 23 | } 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /kms/softkms/testdata/cert.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBpzCCAU2gAwIBAgIQWaY8KIDAfak8aYljelf8eTAKBggqhkjOPQQDAjAdMRsw 3 | GQYDVQQDExJ0ZXN0LnNtYWxsc3RlcC5jb20wHhcNMjAwMTE2MDAwNDU4WhcNMjAw 4 | MTE3MDAwNDU4WjAdMRswGQYDVQQDExJ0ZXN0LnNtYWxsc3RlcC5jb20wWTATBgcq 5 | hkjOPQIBBggqhkjOPQMBBwNCAATlU8P9blFefSWuzYx2g215NJn6yHW95PXeFqQ9 6 | kX1jNo1VmC6Oord3We37iM8QJT4QP9ZDUaAVmJUZSjd+W8H/o28wbTAOBgNVHQ8B 7 | Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQW 8 | BBTn0wonKkm2lLRNYZrKhUukiynvqzAdBgNVHREEFjAUghJ0ZXN0LnNtYWxsc3Rl 9 | cC5jb20wCgYIKoZIzj0EAwIDSAAwRQIhAJ5XqryBIY1X4fl/9l0isV69eQfA0Qo5 10 | 1mjervUcEnOWAiBsmN4frz5YVw7i4UXChVBeZLZfJOKvn5eyh2gEzoq1+w== 11 | -----END CERTIFICATE----- 12 | -------------------------------------------------------------------------------- /kms/sshagentkms/testdata/cert.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBpzCCAU2gAwIBAgIQWaY8KIDAfak8aYljelf8eTAKBggqhkjOPQQDAjAdMRsw 3 | GQYDVQQDExJ0ZXN0LnNtYWxsc3RlcC5jb20wHhcNMjAwMTE2MDAwNDU4WhcNMjAw 4 | MTE3MDAwNDU4WjAdMRswGQYDVQQDExJ0ZXN0LnNtYWxsc3RlcC5jb20wWTATBgcq 5 | hkjOPQIBBggqhkjOPQMBBwNCAATlU8P9blFefSWuzYx2g215NJn6yHW95PXeFqQ9 6 | kX1jNo1VmC6Oord3We37iM8QJT4QP9ZDUaAVmJUZSjd+W8H/o28wbTAOBgNVHQ8B 7 | Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQW 8 | BBTn0wonKkm2lLRNYZrKhUukiynvqzAdBgNVHREEFjAUghJ0ZXN0LnNtYWxsc3Rl 9 | cC5jb20wCgYIKoZIzj0EAwIDSAAwRQIhAJ5XqryBIY1X4fl/9l0isV69eQfA0Qo5 10 | 1mjervUcEnOWAiBsmN4frz5YVw7i4UXChVBeZLZfJOKvn5eyh2gEzoq1+w== 11 | -----END CERTIFICATE----- 12 | -------------------------------------------------------------------------------- /pemutil/testdata/cosign.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED COSIGN PRIVATE KEY----- 2 | eyJrZGYiOnsibmFtZSI6InNjcnlwdCIsInBhcmFtcyI6eyJOIjozMjc2OCwiciI6 3 | OCwicCI6MX0sInNhbHQiOiJuaExoelFuMGFxUUVidEtCaGM0SENYRHRoNVVKaFdq 4 | Z2pTaDhnKzRXZURJPSJ9LCJjaXBoZXIiOnsibmFtZSI6Im5hY2wvc2VjcmV0Ym94 5 | Iiwibm9uY2UiOiI1Uk95VEkwTHRETkdvbjJkVytLWnhrOHE0L2hQZEc0diJ9LCJj 6 | aXBoZXJ0ZXh0IjoiQi9UUjVvSE1qNEdoNmJmYlNOM0xpZnpMRjBma0dzbDVSZksx 7 | ZUs3bFlPSUZMWjdnekRZS1htbG16aGtmREM4L0ZJZWQ3eGlOUnQ1TW5YcnZFVjlU 8 | TTBkOWoxQnhyRytEM1RyNUZsNFJ0dmdaN3F1U0FJaytwWDVscVZ2ZHNMRVNiNkdQ 9 | QWxFQXYyeVl6R1JrL2tpbjQvcUtUOGlDcVYxS2RQZ2lCUjJ1QWM2VHc2OEZLMzda 10 | Q0pndHUrM0xCU2pXRENicGsweWNlcGIycFE9PSJ9 11 | -----END ENCRYPTED COSIGN PRIVATE KEY----- 12 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.p384.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABA2L7LStB 3 | AFQM4HnRPCrz07AAAAEAAAAAEAAACIAAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlz 4 | dHAzODQAAABhBNlvZXMQ+zY03+LWod10pNV/CgirdN895D+RxYG+4JUl8jKC+mb0x66xrA 5 | Q+4tIRfCI0N7D5gdn3Eci8WMKZmwu4Q7O6H230qi3Aznsf7s35EMXOEzaPyEBo65PlcMsp 6 | 9QAAAOC0YUZ6dD5j/kVnc+5ahpTzv6gxwDe48RvJeA4YRgxCWKdlHT6pSRzikQVoi1K3Wo 7 | hfBWrnJ1MP1VBqYEvxA0k8POYSCJR43UW0oBP+qV3ihcxUfMpZoLVsDgmTeEnKDyoHM7Bl 8 | WO84yzp2z/gMcz3L6EDripss1X6rmrzhX42buDU7iDHj9QO6W0FplIljlf0MQIaBhpgLCW 9 | 2Cw4LLwbIzAzcDAkX0iMJw79MicZ8XXjVL0lyaq2N/YivHJqV8QAJwHR+oXuHLlt/sWg9g 10 | 2+Kjc6w9rNeW3AH2E7olol/K1w== 11 | -----END OPENSSH PRIVATE KEY----- 12 | -------------------------------------------------------------------------------- /kms/sshagentkms/testdata/ssh.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC2H93vNENu/nrujjopPphioL8RV0OlnybSvMh2ugkv5EdUNc1DWlTeWsL0hZ+TKNf5jA72McZuton4KCicCSXfqa0vM0LjrjlAZLb9Z0WpFHqZALPu/gbqc5oU1IJ4SsyGDR+fh/uN2pel3SFijMimS1FU1hymLZEyavx78pp2vkRVB9thmB0oiXU7paz07dDUGEsaL0aKkSy1RO+OrFnMXuhSBYofniPl4c1d1sWoqqcrw01CbKk0tgYOxMFAcb3NGz6jTsLZ+g7110g7Y4JqtwFZl8aVjTmT9mESasQ442HatIuEnCrD4QmBB5TQ+h78iqMXLuOdNGSL6157Z6UFhW8dg9Kh9loGZfuLbWzx4FGX9mIXHeKnoTczniZe8pntK4Daqr9hbQh4rInkNK4vT6xEDKJJDYhyzJvdgq/oteiO4lOYn0eD2/j5o4/E5CG81+HdvuwiH9ybPV2r9tpsvI45GtscoPEgkwTtU8yymZ11X3AmAHga7V5Y6JH8K6/qOphZN+JYkMiiplEPmcXW0Woq1nmICqR+W/gpujXS2/qdOVdHpNa4+7Zn+lmnH4037tDFVRKVGDFvtFNVwdG+mB3RM0RcZ25HxqtZUOU17A6Z/koWuhbUhf/JHU68TlGwOLHFxfs1765KWr2GijL1X8inR99wX8qDQ0mg/Cucgw== ssh.test.smallstep.com 2 | -------------------------------------------------------------------------------- /tpm/internal/close/close_others.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | 3 | package closer 4 | 5 | import ( 6 | "io" 7 | 8 | "github.com/google/go-tpm/tpmutil" 9 | "github.com/smallstep/go-attestation/attest" 10 | 11 | "go.step.sm/crypto/tpm/internal/socket" 12 | ) 13 | 14 | func closeRWC(rwc io.ReadWriteCloser) error { 15 | if _, ok := rwc.(*tpmutil.EmulatorReadWriteCloser); ok { 16 | return nil // EmulatorReadWriteCloser automatically closes on every write/read cycle 17 | } 18 | return rwc.Close() 19 | } 20 | 21 | func attestTPM(t *attest.TPM, c *attest.OpenConfig) error { 22 | if _, ok := c.CommandChannel.(*socket.CommandChannelWithoutMeasurementLog); ok { 23 | return nil // backed by tpmutil.EmulatorReadWriteCloser; already closed 24 | } 25 | return t.Close() 26 | } 27 | -------------------------------------------------------------------------------- /kms/apiv1/registry.go: -------------------------------------------------------------------------------- 1 | package apiv1 2 | 3 | import ( 4 | "context" 5 | "sync" 6 | ) 7 | 8 | var registry = new(sync.Map) 9 | 10 | // KeyManagerNewFunc is the type that represents the method to initialize a new 11 | // KeyManager. 12 | type KeyManagerNewFunc func(ctx context.Context, opts Options) (KeyManager, error) 13 | 14 | // Register adds to the registry a method to create a KeyManager of type t. 15 | func Register(t Type, fn KeyManagerNewFunc) { 16 | registry.Store(t.normalize(), fn) 17 | } 18 | 19 | // LoadKeyManagerNewFunc returns the function initialize a KayManager. 20 | func LoadKeyManagerNewFunc(t Type) (KeyManagerNewFunc, bool) { 21 | v, ok := registry.Load(t.normalize()) 22 | if !ok { 23 | return nil, false 24 | } 25 | fn, ok := v.(KeyManagerNewFunc) 26 | return fn, ok 27 | } 28 | -------------------------------------------------------------------------------- /internal/bcrypt_pbkdf/README: -------------------------------------------------------------------------------- 1 | Go implementation of bcrypt_pbkdf(3) from OpenBSD 2 | (a variant of PBKDF2 with bcrypt-based PRF). 3 | 4 | 5 | USAGE 6 | 7 | func Key(password, salt []byte, rounds, keyLen int) ([]byte, error) 8 | 9 | 10 | Key derives a key from the password, salt and rounds count, returning a 11 | []byte of length keyLen that can be used as cryptographic key. 12 | 13 | Remember to get a good random salt of at least 16 bytes. Using a higher 14 | rounds count will increase the cost of an exhaustive search but will also 15 | make derivation proportionally slower. 16 | 17 | 18 | REFERENCES 19 | 20 | * https://github.com/dchest/bcrypt_pbkdf 21 | * http://www.tedunangst.com/flak/post/bcrypt-pbkdf 22 | * http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libutil/bcrypt_pbkdf.c 23 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.p521.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS 3 | 1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQBKzI3QSp1a2e1zMulZl1uFF1Y2Dnv 4 | LSIwEu837hOV1epYEgNveAhGNm57TuBqYtnZeVfd2pzaz7CKX6N4B33N1XABQ5Ngji7lF2 5 | dUbmhNqJoMh43ioIsQNBaBenhmRpYP6f5k8P/7JZMIsLhkJk2hykb8maSZ+B3PYwPMNBdS 6 | vP+0sHQAAAEYIsr2CCLK9ggAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ 7 | AAAIUEASsyN0EqdWtntczLpWZdbhRdWNg57y0iMBLvN+4TldXqWBIDb3gIRjZue07gamLZ 8 | 2XlX3dqc2s+wil+jeAd9zdVwAUOTYI4u5RdnVG5oTaiaDIeN4qCLEDQWgXp4ZkaWD+n+ZP 9 | D/+yWTCLC4ZCZNocpG/Jmkmfgdz2MDzDQXUrz/tLB0AAAAQgEdeH+im6iRcP/juTAoeSHo 10 | ExLtWhgL4JYqRwcOnzCKuLOPjEY/HSOuc+HRrbN9rbjsq+PcPHYe1NnkzXk0IW8hxQAAAB 11 | NtYXJpYW5vQGVuZG9yLmxvY2FsAQIDBAUGBw== 12 | -----END OPENSSH PRIVATE KEY----- 13 | -------------------------------------------------------------------------------- /tpm/internal/key/key_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package key 4 | 5 | import ( 6 | "fmt" 7 | "io" 8 | ) 9 | 10 | func create(_ io.ReadWriteCloser, keyName string, config CreateConfig) ([]byte, error) { 11 | pcp, err := openPCP() 12 | if err != nil { 13 | return nil, fmt.Errorf("failed to open PCP: %w", err) 14 | } 15 | defer pcp.Close() 16 | 17 | _, pub, _, err := pcp.NewKey(keyName, &KeyConfig{Algorithm: Algorithm(config.Algorithm), Size: config.Size}) 18 | if err != nil { 19 | return nil, fmt.Errorf("pcp failed to mint application key: %w", err) 20 | } 21 | 22 | out := serializedKey{ 23 | Encoding: keyEncodingOSManaged, 24 | TPMVersion: uint8(2), // hardcoded to not import github.com/google/go-attestation/attest 25 | Name: keyName, 26 | Public: pub, 27 | } 28 | 29 | return out.Serialize() 30 | } 31 | -------------------------------------------------------------------------------- /kms/tpmkms/tpmkms_others_test.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | 3 | package tpmkms 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | 11 | "go.step.sm/crypto/kms/apiv1" 12 | "go.step.sm/crypto/tpm" 13 | ) 14 | 15 | func TestNew_no_windows(t *testing.T) { 16 | got, err := New(t.Context(), apiv1.Options{ 17 | URI: "tpmkms:enable-cng=true", 18 | }) 19 | assert.Error(t, err) 20 | assert.Nil(t, got) 21 | } 22 | 23 | func TestNewWithTPM_no_windows(t *testing.T) { 24 | tp, err := tpm.New() 25 | require.NoError(t, err) 26 | 27 | got, err := NewWithTPM(t.Context(), tp, WithWindowsCertificateStore("", "")) 28 | assert.Error(t, err) 29 | assert.Nil(t, got) 30 | 31 | got, err = NewWithTPM(t.Context(), tp, WithWindowsIntermediateStore("", "")) 32 | assert.Error(t, err) 33 | assert.Nil(t, got) 34 | } 35 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.p521.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAVXURLKc 3 | jVTtli0RBAkjB6AAAAEAAAAAEAAACsAAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlz 4 | dHA1MjEAAACFBAErMjdBKnVrZ7XMy6VmXW4UXVjYOe8tIjAS7zfuE5XV6lgSA294CEY2bn 5 | tO4Gpi2dl5V93anNrPsIpfo3gHfc3VcAFDk2COLuUXZ1RuaE2omgyHjeKgixA0FoF6eGZG 6 | lg/p/mTw//slkwiwuGQmTaHKRvyZpJn4Hc9jA8w0F1K8/7SwdAAAASC8XZTQI1uwNSUIMh 7 | bakjv0AIJeearpkSE7EV6AJM1GkliQd+1Y36tLF/e4H1HZzz3G2r0RfZPYGKvGUYjOQDv/ 8 | dS/rGEFbicC1hCrpjyP44wkH1pjzNFMhjei6e/oJ2/NvW6r5Hg/FEE8cqWmRajDIMCeuOB 9 | BRS77P2ArGcscYyX4zbD1Ug7at9ouYhrPpAa/P8RWMFGBRdlrVb0QJ6IIBwFig++EJ0Nb9 10 | P6vvh//tB0TbD+1hFXB7eMeuK3dYaZig429d53Yqj8BzCkH8dXOps6nNcjF5yhNdfVwDTZ 11 | QzV/B3jHGd+70qsj5VDPI4JI0dX8FrerQ2MlYzJ00uHMx9Tm7a/yaxemG2CvZnELYxGDNK 12 | UpKQcNjgpbvQz7QVo4U= 13 | -----END OPENSSH PRIVATE KEY----- 14 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.rsa4096.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2SMvtz+OAZ7sMUv5BpMk 3 | 6y0Gun4pony8ocAS/rnZKmQxt33tY52Jcnl5DlVa1UgykladJOlPLydvcht7eOFp 4 | CJYKrdJbmMNtVvZxb6omsA+xuULDoHipYm2hKkZCXTqunWen3qqEA2XM3JJzBgN3 5 | vj/WhX9M3wwFDyB4vnX2nHqpeqySNP1VXd+vIFKei/bL4Lw/IoPqn/iDQf2XtnMk 6 | PKmFlrmg4DD8eMPmqX9hhQDBVyKkoxRyXDbtHKjopLCVK8LSfi9M7zpF/CQObaDt 7 | UKxG4c8Hf6u+iU5xSERXLldKq/SDBi7HtddKW8bekwVjRD8sIDb8+1TSia0AHFEN 8 | Ki0sWTAUu2iiPEBxDjCspnLBm43YVad8Z8s0TqWGStWuIKXWwzZL5S5Shg1JsIjq 9 | LgdlkjZRiY9W/Snot6th70lXlg0KFq/YIDJLLvBPKpHeCb2oxGbeRGjb6pDH6cZV 10 | mADdF+3gJQBaPAa3yJCqBu4ZuoBQngGA1ZrCI09QYqnVHM2xoz7Z+8NI2/gAdIkq 11 | mNMsoD0FA1HBouagvHXtKlotWa/IQ1W/slE/X/pxXvIQk9hDuE9XAT1pFIy6x+b4 12 | Xfw3ol6M4O4Wbz5gSllIXbR0jf+ah7sIrXnBPuYz2zkgFViYQNaJgOFx/EKtKBzf 13 | rXEkkp9D/lK0kMhDPZjb9I8CAwEAAQ== 14 | -----END PUBLIC KEY----- 15 | -------------------------------------------------------------------------------- /x509util/testdata/example.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "subject": {{ toJson .Insecure.CR.Subject }}, 3 | "sans": {{ toJson .SANs }}, 4 | {{- if .Insecure.CR.EmailAddresses }} 5 | "emailAddresses": {{ toJson .Insecure.CR.EmailAddresses }}, 6 | {{- end }} 7 | {{- if .Token }} 8 | "uris": "{{ .Token.iss }}#{{ .Token.sub }}", 9 | {{- end }} 10 | "notBefore": "{{ dateInZone "2006-01-02T15:04:05Z07:00" .Token.nbf "UTC" }}", 11 | "notAfter": "{{ .Webhooks.Test.notAfter }}", 12 | {{- if typeIs "*rsa.PublicKey" .Insecure.CR.PublicKey }} 13 | {{- if lt .Insecure.CR.PublicKey.Size 384 }} 14 | {{ fail "Key length must be at least 3072 bits" }} 15 | {{- end }} 16 | {{- end }} 17 | {{- if typeIs "*rsa.PublicKey" .Insecure.CR.PublicKey }} 18 | "keyUsage": ["keyEncipherment", "digitalSignature"], 19 | {{- else }} 20 | "keyUsage": ["digitalSignature"], 21 | {{- end }} 22 | "extKeyUsage": ["serverAuth", "clientAuth"] 23 | } -------------------------------------------------------------------------------- /tpm/caps_test.go: -------------------------------------------------------------------------------- 1 | package tpm 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | 8 | "go.step.sm/crypto/tpm/algorithm" 9 | ) 10 | 11 | func Test_Capabilities_SupportsAlgorithm(t *testing.T) { 12 | caps := &Capabilities{} 13 | assert.False(t, caps.SupportsAlgorithm(algorithm.AlgorithmRSA)) 14 | 15 | caps = &Capabilities{ 16 | Algorithms: []algorithm.Algorithm{algorithm.AlgorithmRSA}, 17 | } 18 | assert.True(t, caps.SupportsAlgorithm(algorithm.AlgorithmRSA)) 19 | } 20 | 21 | func Test_Capabilities_SupportsAlgorithms(t *testing.T) { 22 | caps := &Capabilities{} 23 | assert.False(t, caps.SupportsAlgorithms([]algorithm.Algorithm{algorithm.AlgorithmRSA})) 24 | 25 | caps = &Capabilities{ 26 | Algorithms: []algorithm.Algorithm{algorithm.AlgorithmRSA}, 27 | } 28 | assert.True(t, caps.SupportsAlgorithms([]algorithm.Algorithm{algorithm.AlgorithmRSA})) 29 | } 30 | -------------------------------------------------------------------------------- /tpm/algorithm/algorithm_test.go: -------------------------------------------------------------------------------- 1 | package algorithm 2 | 3 | import ( 4 | "encoding/json" 5 | "math" 6 | "testing" 7 | 8 | "github.com/google/go-tpm/legacy/tpm2" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func Test_AlgorithmString(t *testing.T) { 13 | tests := []struct { 14 | name string 15 | id tpm2.Algorithm 16 | want string 17 | }{ 18 | {"ok/RSA", tpm2.AlgRSA, "RSA"}, 19 | {"ok/3DES", 0x0003, "3DES"}, 20 | {"ok/UNKNOWN", math.MaxUint16, "UNKNOWN_ALGORITHM"}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := Algorithm(tt.id).String(); got != tt.want { 25 | t.Errorf("String() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | 31 | func Test_AlgorithmMarshalJSON(t *testing.T) { 32 | b, err := json.Marshal(Algorithm(tpm2.AlgRSA)) 33 | require.NoError(t, err) 34 | require.JSONEq(t, `"RSA"`, string(b)) 35 | } 36 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.rsa1024.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICWwIBAAKBgQCztZjbIWsnC88Npdq6YHwKi41OYPM8wD4Bcn7TU4NcEh5zLiQ9 3 | rpxoAxKmxZtSFD7PbTkQkNa8rHN5vX9qWrrwrAIxX/vAiVo+ZvSNoPeG1Bn18xJ3 4 | 4oLPUUv3IkVCSBFWcZ1NBUhde+KabeaGKNb3bHM+4btBb4TLZwhh6EC6RwIDAQAB 5 | AoGAENNX1Gx0k9tPL3/v0rNl6bbXLBd3rqBxLcGCjlarXdt0bmRLkFrg2fwvqt2l 6 | hTHQD6uyRBLLiC69QRC09Ug5aFb22BQlhcSgy8K8gRAXb9Ekz+9riTiJk/gBoVSk 7 | YjsoAIzYuE4BXz3CR2R4Sywh2v/7JDitCZsXHaVhCNpWQMECQQDjZrHOtGeUfsFo 8 | 8c9WxGmBNoGned4zaknEK+UAAGCBgR2F9ChkEQT1f1A13e2Hl0XzZmXflOvaDGBI 9 | WvzwxribAkEAyk9wbFSeSlyj5U0D2wi61oif16JAu1QUAQr82ESYXarE5pnoms39 10 | cUwLhdCJwmpzpi+3zlz6IEmpA10HtG0xxQJAGoCffG2+HKphNC/qcDxX531IwxIK 11 | +YcLrddHyyZAGRfJLxFzm6X4I/yAhqakxka1Glb2zIX4ruL+XbBtBkrCvQJAXS4T 12 | gMHEmklq74z2TqcJrxAEVwQTPnSuNgDCjjWh29pwkCmpOcvQhKNa10pCePogxBVM 13 | Wk72oXJr1vG9P7vfZQJAduCw0ydHAg7Mh70A3qLMW7+Hj8pMNo7vNKjJE/HDtHWb 14 | tQEQ/FjyyQ3jtxoAhDx2HwxKO+ksUO/4FOtuuG3pKw== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /jose/testdata/jwks.json: -------------------------------------------------------------------------------- 1 | { 2 | "keys": [ 3 | { 4 | "use": "sig", 5 | "kty": "OKP", 6 | "kid": "qiCJG7r2L80rmWRrZMPfpanQHmZRcncOG7A7MBWn9qM", 7 | "crv": "Ed25519", 8 | "alg": "EdDSA", 9 | "x": "L4WYxHsMVaspyhWuSp84v2meEYMEUdYnrn-w-jqP6iw" 10 | }, 11 | { 12 | "use": "sig", 13 | "kty": "EC", 14 | "kid": "V93A-Yh7Bhw1W2E0igFciviJzX4PXPswoVgriehm9Co", 15 | "crv": "P-256", 16 | "alg": "ES256", 17 | "x": "JtPSvIKayHsCHobDnNWtOdoroh-MDwKQSYMW6Mo4cfU", 18 | "y": "tP7xR5rpu6azzZsozdmzouyVByuTUDYSSAELTOAtu7g" 19 | }, 20 | { 21 | "use": "sig", 22 | "kty": "oct", 23 | "alg": "HS256", 24 | "kid": "duplicated", 25 | "k": "TUE5VnJDa3gzbDRtc3lWa1liRW1pUDVZNHBBRnNUNXo" 26 | }, 27 | { 28 | "use": "sig", 29 | "kty": "oct", 30 | "alg": "HS256", 31 | "kid": "duplicated", 32 | "k": "SzhwbXo1bXNZMWtmeVhrTnpHNDZZNkdLUE1NTTRWYUw" 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /tpm/simulator/simulator_disabled.go: -------------------------------------------------------------------------------- 1 | //go:build !tpmsimulator 2 | 3 | package simulator 4 | 5 | import ( 6 | "errors" 7 | "io" 8 | ) 9 | 10 | type NoSimulator struct { 11 | } 12 | 13 | func New() (Simulator, error) { 14 | return &NoSimulator{}, errors.New("no simulator available") 15 | } 16 | 17 | func (s *NoSimulator) Open() error { 18 | return errors.New("cannot open: no simulator available") 19 | } 20 | 21 | func (s *NoSimulator) Close() error { 22 | return errors.New("cannot close: no simulator available") 23 | } 24 | 25 | func (s *NoSimulator) MeasurementLog() ([]byte, error) { 26 | return nil, errors.New("cannot get measurement log: no simulator available") 27 | } 28 | 29 | func (s *NoSimulator) Read([]byte) (int, error) { 30 | return -1, errors.New("cannot read: no simulator available") 31 | } 32 | 33 | func (s *NoSimulator) Write([]byte) (int, error) { 34 | return -1, errors.New("cannot write: no simulator available") 35 | } 36 | 37 | var _ Simulator = (*NoSimulator)(nil) 38 | var _ io.ReadWriteCloser = (*NoSimulator)(nil) 39 | -------------------------------------------------------------------------------- /tpm/internal/key/create.go: -------------------------------------------------------------------------------- 1 | package key 2 | 3 | import "io" 4 | 5 | // Create creates a new TPM key without attesting it and returns a 6 | // serialized representation of it. The serialized format is compatible 7 | // with the `go-attestation` format. Most of the code in this package 8 | // is in fact copied from `go-attestation`, as large parts of its code 9 | // are not publicly available at the moment. The code is useful, as it 10 | // allows keys to be created in exactly the same way `go-attestation` 11 | // creates them, except without attesting them. Both types of keys can 12 | // be used for similar purposes, but only keys attested by an AK can be 13 | // proved to be actually only resident in a TPM. 14 | // 15 | // TODO: it might be an option to make some more things public in the 16 | // `go-attestation` package, or to change some of the logic of the 17 | // `NewKey` function that makes the AK optional. 18 | func Create(rwc io.ReadWriteCloser, keyName string, config CreateConfig) ([]byte, error) { 19 | return create(rwc, keyName, config) 20 | } 21 | -------------------------------------------------------------------------------- /internal/utils/asn1/asn1_test.go: -------------------------------------------------------------------------------- 1 | package asn1utils 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestIsPrintableString(t *testing.T) { 10 | type args struct { 11 | s string 12 | asterisk bool 13 | ampersand bool 14 | } 15 | tests := []struct { 16 | name string 17 | args args 18 | want bool 19 | }{ 20 | {"empty", args{"", false, false}, true}, 21 | {"a", args{"a", false, false}, true}, 22 | {"spaces and caps", args{"My Leaf", false, false}, true}, 23 | {"default allowed punctuation", args{`(Hi+,-./):=?`, false, false}, true}, 24 | {"asterisk not allowed", args{"*", false, false}, false}, 25 | {"ampersand not allowed", args{"&", false, false}, false}, 26 | {"asterisk allowed", args{"*", true, false}, true}, 27 | {"ampersand allowed", args{"&", false, true}, true}, 28 | } 29 | for _, tt := range tests { 30 | t.Run(tt.name, func(t *testing.T) { 31 | assert.Equal(t, tt.want, IsPrintableString(tt.args.s, tt.args.asterisk, tt.args.ampersand)) 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.rsa1024.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: AES-128-CBC,031BB2B8FFEE426F60E8200DF919F640 4 | 5 | Pg+LE+2pEeWBJpGgXQd46boBmhv5Sa0Bf3TIv0rhpQuYxmPk5zk9mGYnRSDeFZPU 6 | tGSxV9NA+V6Kr2UYsfcF4I8o1git0c915vUTe5I0uW++vt4NZIqsxliQarFjuJCt 7 | mlZq2606BDCkKC8NgwMG4fpF4pJR4JtG10+q89P9VpfKwE91imhR4B/AYH6V0C9H 8 | XriTLlpbSz81ibBgLdVL+LI/dyfyEl80B5Yle3ZXVgES7ljThWQYMS/US1sxgVcD 9 | Q9co/RlQP0SLXE1nqMm/L8zcZVUYlwo0mPmLEd+lHiNVEkGqDuTg2m0uORKj6PxC 10 | uVowrF5iz7VlggiilC080f9apeHHVlRQkIal+N5mtnLR4BrO/xLg7riOhS1h61nB 11 | 0BYN4HjY9jjCyGUz/+Em6a3emXIJqiT+i3sMkSstSAq5Cfct3WF+aAbeGFfiGP/H 12 | 1mZmcXN79u0Db8DzXrD03TBVYi7m9jERkYtHR9sL1qjg7CghQGfL6WhFGZqQnmBW 13 | emgWMOxgkCBBjxeCOo9nLIhKrSP1QspzqFNYyXccFvxp4XgapWmhA+gp+aevuKkC 14 | R9RBfLBabppMoUQR6rQWwMGUCvUWUfFMivrPnqPN2fiFOWvp0DSORvmVxPT8LR35 15 | Ui2ubZgTI0gVHzC4FSWQETtr2TrpwTla8jFA57KfwrwX89qaLCTokbexZtQk8oBH 16 | V8H9kQ7k+eLOISYKvXXt/gCmU7bY76nRX9U4tJg0Z2rpEp5DE4RdnNsMUV1e2eT2 17 | X/7JW48wNudEkbkSKMrbUsZo131dZxA0mmt3KG9H5zY= 18 | -----END RSA PRIVATE KEY----- 19 | -------------------------------------------------------------------------------- /nssdb/metadata_test.go: -------------------------------------------------------------------------------- 1 | package nssdb 2 | 3 | import ( 4 | "context" 5 | "database/sql" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestGetMetadata(t *testing.T) { 13 | ctx := context.Background() 14 | 15 | for _, v := range nssVersions { 16 | db := v.connect(t) 17 | 18 | t.Run(v.name("ok"), func(t *testing.T) { 19 | got, err := db.GetMetadata(ctx, "password") 20 | require.NoError(t, err) 21 | 22 | assert.Equal(t, "password", got.ID) 23 | assert.NotEmpty(t, got.Item1) 24 | assert.NotEmpty(t, got.Item2) 25 | }) 26 | 27 | t.Run(v.name("not found"), func(t *testing.T) { 28 | _, err := db.GetMetadata(ctx, "notfound") 29 | assert.ErrorIs(t, err, sql.ErrNoRows) 30 | }) 31 | } 32 | } 33 | 34 | func TestGetPassword(t *testing.T) { 35 | for _, v := range nssVersions { 36 | db := v.connect(t) 37 | 38 | t.Run(v.name("ok"), func(t *testing.T) { 39 | _, err := db.GetPassword(context.Background()) 40 | require.NoError(t, err) 41 | }) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tpm/storage/tpmstore.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import "context" 4 | 5 | type contextKey struct{} 6 | 7 | // NewContext adds TPMStore `t` to the context. 8 | func NewContext(ctx context.Context, t TPMStore) context.Context { 9 | return context.WithValue(ctx, contextKey{}, t) 10 | } 11 | 12 | // FromContext retrieves a TPMStore from the context. 13 | // 14 | // It panics when there's no TPMStore present. 15 | func FromContext(ctx context.Context) TPMStore { 16 | return ctx.Value(contextKey{}).(TPMStore) 17 | } 18 | 19 | // TPMStore is the interface that TPM storage implementations 20 | // need to implement. 21 | type TPMStore interface { 22 | ListKeys() ([]*Key, error) 23 | ListKeyNames() []string 24 | GetKey(name string) (*Key, error) 25 | AddKey(key *Key) error 26 | UpdateKey(key *Key) error 27 | DeleteKey(name string) error 28 | 29 | ListAKs() ([]*AK, error) 30 | ListAKNames() []string 31 | GetAK(name string) (*AK, error) 32 | AddAK(ak *AK) error 33 | UpdateAK(ak *AK) error 34 | DeleteAK(name string) error 35 | 36 | Persist() error 37 | Load() error 38 | } 39 | -------------------------------------------------------------------------------- /nssdb/testdata/README.md: -------------------------------------------------------------------------------- 1 | # Testdata 2 | 3 | The directories contain NSS sqlite certificate and key database files created and modified with the `certutil` and `pk12util1` commands. 4 | The newest supported version is 3.107. The NSS test database for this version was generated in a Fedora 41 container. 5 | The oldest supported version is 3.51. The NSS test database for this version was generated in a Fedora 30 container. 6 | (Support for 3.39 generated in a Fedora 28 container could be achieved by implementing PBE with SHA-1 and Triple DES-CBC, the default for encrypting private attributes with that version. Older versions of NSS use the legacy dbm database and do not work with this package.) 7 | 8 | The leaf certificate imported into the NSS test database was generated with these commands: 9 | ```bash 10 | step certificate create root-ca root-ca.crt root-ca.key --profile root-ca --no-password --insecure 11 | step certificate create leaf leaf.crt leaf.key --ca ./root-ca.crt --ca-key ./root-ca.key --no-password --insecure 12 | step certificate p12 leaf.p12 leaf.crt leaf.key --no-password --insecure 13 | ``` 14 | -------------------------------------------------------------------------------- /tpm/context.go: -------------------------------------------------------------------------------- 1 | package tpm 2 | 3 | import "context" 4 | 5 | type contextKey struct{} 6 | 7 | // NewContext adds TPM `t` to the context. 8 | func NewContext(ctx context.Context, t *TPM) context.Context { 9 | return context.WithValue(ctx, contextKey{}, t) 10 | } 11 | 12 | // FromContext returns a TPM from the context. 13 | // 14 | // It panics when there's no TPM in the context. 15 | func FromContext(ctx context.Context) *TPM { 16 | return ctx.Value(contextKey{}).(*TPM) 17 | } 18 | 19 | type internalCallContextKey struct{} 20 | 21 | func internalCall(ctx context.Context) context.Context { 22 | return context.WithValue(ctx, internalCallContextKey{}, true) 23 | } 24 | 25 | func isInternalCall(ctx context.Context) bool { 26 | v, ok := ctx.Value(internalCallContextKey{}).(bool) 27 | return ok && v 28 | } 29 | 30 | type goTPMCallContextKey struct{} 31 | 32 | func goTPMCall(ctx context.Context) context.Context { 33 | return context.WithValue(ctx, goTPMCallContextKey{}, true) 34 | } 35 | 36 | func isGoTPMCall(ctx context.Context) bool { 37 | v, ok := ctx.Value(goTPMCallContextKey{}).(bool) 38 | return ok && v 39 | } 40 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.rsa1024.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn 3 | NhAAAAAwEAAQAAAIEA34M9Dd9njEDCC243aPwnZ3byAt6+y9dgodCDu+weINmluzGotYzc 4 | fx68+7LL0ro8qW8OnfEwZjbM26fieHKFR4HWWbs/LCqQCpojYGVaradvks07D6cxr38bCH 5 | DzixJPtjB3VHYS1mnAd+Yn6klvbWNhNZwP11bm/6TxaeXXHMUAAAIIbIMl/WyDJf0AAAAH 6 | c3NoLXJzYQAAAIEA34M9Dd9njEDCC243aPwnZ3byAt6+y9dgodCDu+weINmluzGotYzcfx 7 | 68+7LL0ro8qW8OnfEwZjbM26fieHKFR4HWWbs/LCqQCpojYGVaradvks07D6cxr38bCHDz 8 | ixJPtjB3VHYS1mnAd+Yn6klvbWNhNZwP11bm/6TxaeXXHMUAAAADAQABAAAAgFd0d3A1KM 9 | QFFqf4US//8b8XGGytEUSbGlFWUCU4pzU9VA6hyJx46FHJCjMF66ChhFjbfoGoPMLR0Ghm 10 | EUQFs0XjPrPzmgHa5O16oYqgXgds4n/aDGVumAOMW1ggTjQHBfXbTL2nwoWl+v5BKnRFkN 11 | oEDQbDrw7VhPCkHbwnj3zBAAAAQCRxoNw8KVkjIDo+epgU8Bz3RqlkiozeEGfnrbwN4+5e 12 | 7yGxUlI6Q7YsfJb775lsiMBGwBQFLfj9e+wQMZZzeOYAAABBAPKB9+6c/sPWsbOlyuE3dI 13 | XvZdlcz4gK0YrtFXHpBnU0XDYNbaaWWSWbnC3NFYqdr9ps4GCQ97rMerETiJzscLUAAABB 14 | AOvyuV6E1QK+frD4YpzRz95YICDwooGsAICI6V2tx8xv/ZIfdQRBgRrOl0DoieQTUwt5io 15 | F9ZAqj4xLuR563VdEAAAATbWFyaWFub0BlbmRvci5sb2NhbA== 16 | -----END OPENSSH PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /tpm/internal/key/key_others.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | 3 | package key 4 | 5 | import ( 6 | "fmt" 7 | "io" 8 | 9 | "github.com/google/go-tpm/legacy/tpm2" 10 | ) 11 | 12 | func create(rwc io.ReadWriteCloser, keyName string, config CreateConfig) ([]byte, error) { 13 | srk, _, err := getPrimaryKeyHandle(rwc, commonSrkEquivalentHandle) 14 | if err != nil { 15 | return nil, fmt.Errorf("failed to get SRK handle: %w", err) 16 | } 17 | 18 | tmpl, err := templateFromConfig(&KeyConfig{Algorithm: Algorithm(config.Algorithm), Size: config.Size}) 19 | if err != nil { 20 | return nil, fmt.Errorf("incorrect key options: %w", err) 21 | } 22 | 23 | blob, pub, creationData, _, _, err := tpm2.CreateKey(rwc, srk, tpm2.PCRSelection{}, "", "", tmpl) 24 | if err != nil { 25 | return nil, fmt.Errorf("CreateKey() failed: %w", err) 26 | } 27 | 28 | out := serializedKey{ 29 | Encoding: keyEncodingEncrypted, 30 | TPMVersion: uint8(2), // hardcoded to not import github.com/google/go-attestation/attest 31 | Name: keyName, 32 | Public: pub, 33 | Blob: blob, 34 | CreateData: creationData, 35 | } 36 | 37 | return out.Serialize() 38 | } 39 | -------------------------------------------------------------------------------- /nssdb/testdata/fixtures.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | function main() { 6 | cd /nssdb 7 | # Create a new database. This will generate key4.db, cert9.db and pkcs11.txt files. 8 | certutil -N -d . --empty-password 9 | 10 | # Import our leaf certificate and private key into the NSS database. This will 11 | # add one record to the nssPrivate table in the key4.db for the private key and 12 | # two records to the nssPublic table in the cert9.db - one for the certificate 13 | # and one for its public key. This will also add a record to the metaData table 14 | # in the key4.db that holds a signature of the private key's value. 15 | pk12util -i /leaf.p12 -d . -W '' 16 | 17 | # column a0 holds the CKA_CLASS attribute 18 | certID=$(sqlite3 cert9.db "select id from nssPublic where a0 = X'00000001'") 19 | pubKeyID=$(sqlite3 cert9.db "select id from nssPublic where a0 = X'00000002'") 20 | privateKeyID=$(sqlite3 key4.db "select id from nssPrivate where a0 = X'00000003'") 21 | 22 | echo "certificate ${certID}" >> ids.txt 23 | echo "public-key ${pubKeyID}" >> ids.txt 24 | echo "private-key ${privateKeyID}" >> ids.txt 25 | } 26 | 27 | main "$@" 28 | -------------------------------------------------------------------------------- /tlsutil/cache.go: -------------------------------------------------------------------------------- 1 | package tlsutil 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | type credentialsCacheElement struct { 8 | sni string 9 | renewer *Renewer 10 | } 11 | 12 | type credentialsCache struct { 13 | CacheStore *sync.Map 14 | } 15 | 16 | func newCredentialsCache() *credentialsCache { 17 | return &credentialsCache{ 18 | CacheStore: new(sync.Map), 19 | } 20 | } 21 | 22 | func (c *credentialsCache) Load(domain string) (*credentialsCacheElement, bool) { 23 | v, ok := c.CacheStore.Load(domain) 24 | if !ok { 25 | return nil, false 26 | } 27 | e, ok := v.(*credentialsCacheElement) 28 | return e, ok 29 | } 30 | 31 | func (c *credentialsCache) Store(domain string, v *credentialsCacheElement) { 32 | c.CacheStore.Store(domain, v) 33 | } 34 | 35 | func (c *credentialsCache) Delete(domain string) { 36 | c.CacheStore.Delete(domain) 37 | } 38 | 39 | func (c *credentialsCache) Range(fn func(domain string, v *credentialsCacheElement) bool) { 40 | c.CacheStore.Range(func(k, v interface{}) bool { 41 | if domain, ok := k.(string); ok { 42 | if e, ok := v.(*credentialsCacheElement); ok { 43 | return fn(domain, e) 44 | } 45 | } 46 | return true 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /x509util/testdata/challengePasswordUTF8.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIC5TCCAc0CAQAwFTETMBEGA1UEAxMKY29tbW9uTmFtZTCCASIwDQYJKoZIhvcN 3 | AQEBBQADggEPADCCAQoCggEBAMpfsoCGJnHQWgd98laaURBT/P/CF3lKkTiilu4M 4 | HZq12AbgKe5K4daFg/X4l1vm837wMkQX10WX9lExyBPXQ6gMCtbwOUyaNbhhpWBT 5 | 3x4pBVZW6ZTsr95FTWjMCsZbT4sKAI9Do4SgYzZoRN/Z1rD95ia46qJtr94nJK5p 6 | JCifopn0n4iZl0cz63NO5ed2fFusfTd7/uXcerLIt/LBCVSH3Os0XeFBzVvj5HmA 7 | HrYzjuIMM7LNcC80lyDSTjB5dNyncX5//KFlBcpjYbTDf7iX+fNi9gqWpAQkblJA 8 | lokUczDkVAM8vlPOL+B0pEgbi5lq6mmSaUwWg0GyZv6YVSECAwEAAaCBijATBgkq 9 | hkiG9w0BCQcxBgwE8J+UkDBzBgkqhkiG9w0BCQ4xZjBkMFAGA1UdEQRJMEeCB2Zv 10 | by5jb22CB2Jhci5jb22BDHJvb3RAZm9vLmNvbYcQAAAAAAAAAAAAAAAAAAAAAYYT 11 | bWFpbHRvOnJvb3RAZm9vLmNvbTAQBgMqAwQBAf8EBmZvb2JhcjANBgkqhkiG9w0B 12 | AQsFAAOCAQEALf4qgcXqS9LONJJcS5LvgMNJF18/rwOnZuL1xBx+ml9gHH9kPp8/ 13 | SOoGjsXCE6GSZ7FZ7ZZDEf/jb5aurEO4jzZ0RbFRpC16yrzZaRkuh6Tj91lc45HY 14 | mc1WwAwXA373OJ4Xzc2FznGVBVh089gvodltZqjbGkBWIlziLf1PdPG/ig89eXCp 15 | JPCJdAB3BBBJLKLMJV5lSaaXHUq81dDm/hliksywmg5GS3pfYPEP9PkF2lRbmbj7 16 | vkosVv1fqLRIdC9rE25izwlEeHTomdLKXY2asueBdrRnSDN4h8QN5wpzI/wENkpI 17 | Crf8d9KpmQH4yVFs1afRqyRBlhW2haOlbw== 18 | -----END CERTIFICATE REQUEST----- 19 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Create Release 2 | 3 | on: 4 | push: 5 | # Sequence of patterns matched against refs/tags 6 | tags: 7 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 8 | 9 | jobs: 10 | ci: 11 | uses: smallstep/crypto/.github/workflows/ci.yml@master 12 | secrets: inherit 13 | 14 | create_release: 15 | name: Create Release 16 | needs: ci 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Is Pre-release 20 | id: is_prerelease 21 | run: | 22 | set +e 23 | echo ${{ github.ref }} | grep "\-rc.*" 24 | OUT=$? 25 | if [ $OUT -eq 0 ]; then IS_PRERELEASE=true; else IS_PRERELEASE=false; fi 26 | echo "IS_PRERELEASE=${IS_PRERELEASE}" >> "${GITHUB_OUTPUT}" 27 | - name: Create Release 28 | id: create_release 29 | uses: actions/create-release@v1 30 | env: 31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 32 | with: 33 | tag_name: ${{ github.ref }} 34 | release_name: Release ${{ github.ref }} 35 | draft: false 36 | prerelease: ${{ steps.is_prerelease.outputs.IS_PRERELEASE }} 37 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.rsa1024.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABATOWWPK4 3 | fxPP+DRLPifG2jAAAAEAAAAAEAAACXAAAAB3NzaC1yc2EAAAADAQABAAAAgQDfgz0N32eM 4 | QMILbjdo/CdndvIC3r7L12Ch0IO77B4g2aW7Mai1jNx/Hrz7ssvSujypbw6d8TBmNszbp+ 5 | J4coVHgdZZuz8sKpAKmiNgZVqtp2+SzTsPpzGvfxsIcPOLEk+2MHdUdhLWacB35ifqSW9t 6 | Y2E1nA/XVub/pPFp5dccxQAAAhCrwlwmmc1gRIrKsY+5wQ7PfC67X3tyO8377XtNvtRo3A 7 | JE0G/5qG/T3OQ+WX0tAPie7VcUsshlGsdW4KKW356krI8uhlgcpDCs2OM1O0JVK9K4erHW 8 | nxTEXmtVyp2b77oGaoKDnfDEfvzreuacHI99s48YLpPR9TgmFgK3/5bBlHZCyrlYHNMR+0 9 | XI5/SFEsulvGSsi5xrOMHA3XVzLZjq8OJbiIqnhHaHCSDUlc32AcgY07/SgyKJ0yraBV0C 10 | oiWl2KqevwXRbfIbdEKeYE9SbTC8jFGM/TSvfY9I9mehzar/mxuaMCLctRDYBFlhaIwHIZ 11 | 06iv5lSrKiUe/LSdQ/cLRHiSArYHadpvzzu5cQKk72X4GMfAA4bp114WXdYiL3MuRUwlx2 12 | VqKQm2aQQajbTMO/Nh5nP4yvqM00eElFGOBqW3D+6ifoiQn50p/lk4dHH20GJUduOpBmSn 13 | JJQalndr3Eynuc5DaDBfVPxzSJcR/eI0goQD3Zu96Z9Z9bbn8YS9bklw1pw2aloUL46QvU 14 | /33YGK7TSAPCEBuZt9boIs4HmNclNvWzLgPk28zglLpZm5OC9pZJwzIQUk+XukaCfUnSOf 15 | RtpvIoK2qqHjILY111KNgRNaz3imWF/BuMhfa5nEZJvHkF3BMT7TqED/N4OfFWiq7Rj3oX 16 | ENtqtPEQOgyV4gFcXsPPQYVcT3tQxpo= 17 | -----END OPENSSH PRIVATE KEY----- 18 | -------------------------------------------------------------------------------- /x509util/testdata/challengePassword.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIC8jCCAdoCAQAwFTETMBEGA1UEAxMKY29tbW9uTmFtZTCCASIwDQYJKoZIhvcN 3 | AQEBBQADggEPADCCAQoCggEBAMpfsoCGJnHQWgd98laaURBT/P/CF3lKkTiilu4M 4 | HZq12AbgKe5K4daFg/X4l1vm837wMkQX10WX9lExyBPXQ6gMCtbwOUyaNbhhpWBT 5 | 3x4pBVZW6ZTsr95FTWjMCsZbT4sKAI9Do4SgYzZoRN/Z1rD95ia46qJtr94nJK5p 6 | JCifopn0n4iZl0cz63NO5ed2fFusfTd7/uXcerLIt/LBCVSH3Os0XeFBzVvj5HmA 7 | HrYzjuIMM7LNcC80lyDSTjB5dNyncX5//KFlBcpjYbTDf7iX+fNi9gqWpAQkblJA 8 | lokUczDkVAM8vlPOL+B0pEgbi5lq6mmSaUwWg0GyZv6YVSECAwEAAaCBlzAgBgkq 9 | hkiG9w0BCQcxExMRY2hhbGxlbmdlUGFzc3dvcmQwcwYJKoZIhvcNAQkOMWYwZDBQ 10 | BgNVHREESTBHggdmb28uY29tggdiYXIuY29tgQxyb290QGZvby5jb22HEAAAAAAA 11 | AAAAAAAAAAAAAAGGE21haWx0bzpyb290QGZvby5jb20wEAYDKgMEAQH/BAZmb29i 12 | YXIwDQYJKoZIhvcNAQELBQADggEBAJ/MjfJ4D9p2Uf+ZJxs1sfQgdbAIWTTiP/EO 13 | J3RlBpKgFoII4sU/XvuXiOcwjNZxQuVmxgx0JBsX0iTx6AgKwr34IXVFHNFcKD2+ 14 | 582/pB9TqmWQve62GVEQArelgZa/hvYnDUeVwTtnjre95Zp1a7n/2rOZTk2pnxD4 15 | T5dBlKDTDcppKqzlNlhnsXfDbpOt8g6thTovVwHk0fcUif3ODdH/TyZUGdUyiZ13 16 | rhpFuWJnClj+J9SGDRjiEvRP3RzLraDuTGZbqs9UeFkDBIk4s0f0kcwMC8n6an4S 17 | GAV0PCzyJ6mmTaK0ylsue4nVuf7svv/ST/cHmKc+z561joMMAjc= 18 | -----END CERTIFICATE REQUEST----- 19 | -------------------------------------------------------------------------------- /jose/testdata/rsa2048.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDCTCCAfGgAwIBAgIQIdY8a5pFZ/FGUowvuGdJvTANBgkqhkiG9w0BAQsFADAP 3 | MQ0wCwYDVQQDEwR0ZXN0MB4XDTIwMDQyMTA0MDg0MFoXDTIwMDQyMjA0MDg0MFow 4 | DzENMAsGA1UEAxMEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 5 | AL0zsTneONS0eNto7LMlD8GtcUYXqILSEWD07v0HgbIguBT+yC8BozpAT3lyB+oB 6 | BZkFLzfEHAteULngPwlq0R5hsEZJ6lcL1Z9WXwyLE4nkEndIPMA+zQmHnOzoqgKy 7 | 7pIqUnFqSGXtGp384fFF3Y0/qjeFciLnmf+Wn0PneaToY1rDj2Eb9sFf5UDiVaSL 8 | T1NzpSyXOS5uGbGplPe+WE8uEb3u3Vg2VGbEPau2l5MPYroCwSyxqlpKsmzJ558u 9 | vjQ7KpRExSNdb6f0iRfdRMbw3LahrxhbKV1mmM6GD5onmbgBCZpw5htOJj1MzVFZ 10 | OdnoTHmMl/Y/IUdMjv0jG/UCAwEAAaNhMF8wDgYDVR0PAQH/BAQDAgWgMB0GA1Ud 11 | JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUXlQCQL6RymQZnvqY 12 | 15F/GlE3H4UwDwYDVR0RBAgwBoIEdGVzdDANBgkqhkiG9w0BAQsFAAOCAQEArVmO 13 | L5L+NVsnCcUWfOVXQYg/6P8AGdPJBECk+BE5pbtMg0GuH5Ml/vCTBqD+diWC4O0T 14 | ZDxPMhXH5Ehl+67hcqeu4riwB2WvvKOlAqHqIuqVDRHtxwknvS1efstBKVdDC6aA 15 | fIa5f2dmCSxvd8elpcnufEefLGALTSPxg4uMVvpfWUkkmpmvOUpI3gNrlvP2H4KZ 16 | k7hKYz+J4x2jv2pdPWUAtt1U4M8oQ4BCPrrHSxznw2Q5mdCMIB64ZeYnZ+rAMQS6 17 | WnZy1fTC3d0pCs0UCXH5JefBpha1clqHDUkxHA6/1EYYsSlKGFaPEmfv2uw7MFz0 18 | o+yntG34KVdsC8HO3g== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /internal/templates/validate.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "text/template" 8 | ) 9 | 10 | // ValidateTemplate validates a text template results in valid JSON 11 | // when it's executed with empty template data. If template execution 12 | // results in invalid JSON, the template is invalid. When the template 13 | // is valid, it can be used safely. A valid template can still result 14 | // in invalid JSON when non-empty template data is provided. 15 | func ValidateTemplate(data []byte, funcMap template.FuncMap) error { 16 | if len(data) == 0 { 17 | return nil 18 | } 19 | 20 | // prepare the template with our template functions 21 | _, err := template.New("template").Funcs(funcMap).Parse(string(data)) 22 | if err != nil { 23 | return fmt.Errorf("error parsing template: %w", err) 24 | } 25 | 26 | return nil 27 | } 28 | 29 | // ValidateTemplateData validates that template data is 30 | // valid JSON. 31 | func ValidateTemplateData(data []byte) error { 32 | if len(data) == 0 { 33 | return nil 34 | } 35 | 36 | if ok := json.Valid(data); !ok { 37 | return errors.New("error validating json template data") 38 | } 39 | 40 | return nil 41 | } 42 | -------------------------------------------------------------------------------- /internal/utils/asn1/asn1.go: -------------------------------------------------------------------------------- 1 | package asn1utils 2 | 3 | // IsPrintableString reports whether the given s is a valid ASN.1 PrintableString. 4 | // If asterisk is allowAsterisk then '*' is also allowed, reflecting existing 5 | // practice. If ampersand is allowAmpersand then '&' is allowed as well. 6 | func IsPrintableString(s string, asterisk, ampersand bool) bool { 7 | for _, b := range s { 8 | valid := 'a' <= b && b <= 'z' || 9 | 'A' <= b && b <= 'Z' || 10 | '0' <= b && b <= '9' || 11 | '\'' <= b && b <= ')' || 12 | '+' <= b && b <= '/' || 13 | b == ' ' || 14 | b == ':' || 15 | b == '=' || 16 | b == '?' || 17 | // This is technically not allowed in a PrintableString. 18 | // However, x509 certificates with wildcard strings don't 19 | // always use the correct string type so we permit it. 20 | (asterisk && b == '*') || 21 | // This is not technically allowed either. However, not 22 | // only is it relatively common, but there are also a 23 | // handful of CA certificates that contain it. At least 24 | // one of which will not expire until 2027. 25 | (ampersand && b == '&') 26 | 27 | if !valid { 28 | return false 29 | } 30 | } 31 | 32 | return true 33 | } 34 | -------------------------------------------------------------------------------- /jose/testdata/rsa.priv.json: -------------------------------------------------------------------------------- 1 | { 2 | "use": "sig", 3 | "kty": "RSA", 4 | "kid": "CIsktcixZ5GyfkoWFyEV0tp5foASmBV4D-W7clYrCu8", 5 | "alg": "RS256", 6 | "n": "u1pASewznHZwedqjq85vEKRALbEBy57G4VWTrCY0wdFDThAtv3LwZaG1r9b79yDuqroz7PTT2vVQmzXwDQx78gix48XORLToUZrhcWcEhXxsYyTSJuD8groxHPNS_wTxrIH4ZKtFgJhdaOdSs9iFJpFEoq7DaVH89AWOEtAURek-KbkPci50IiQm-3Zwl9CBvDRs8528fGCthBFerm0kCXLw42oIeLJFC_iEHnR1NFzDuVZq6xjK1qp7vLoKMNUkkxmBFMduYOZth9Mf72i-l0VOZVt3gbHirR6RwXXH_K-NS6amGyB82w16g657p7rE3NXyEMMGXjOuObukMTd1jQ", 7 | "e": "AQAB", 8 | "d": "M_UYhSezPH4APVrsLxZl6MiUX9eJ9u1GnHE-Ley-js25C6oi9cgrcRQCrgxB_kwsxD41bk6LflqwCwtPUl8W9I2Cv_c4eAdvsknwoaF_OIHEEU7B1TRp8tsuCahVaRH27-9vcoOpF7uplBEq92NhsctxrGgpG0k4jHgJ6Z-5L5XAowfhyYx_VOKsAXP65270CKzEfibcCVmZGAbQ-ZR-ByDZQRV7ULNGiG1-GxTPiIkKH_pDV3TFk6tzxg2OE0Pym6EuoUbE1YESRJ2mY7VDi_Rg-S2lbjivtw5YUJSp4N2J6_iF0UrVvCzBvpsFQ3jD-Yur78NIcsSU0lA7LGuXJQ", 9 | "p": "8pebnVh_9ckrPCW4XEU_MK0KB0NQeur0LQJw9VRrkL739RnPfrdYh02B4gapkE0O0QK6PFQqhYyrf5WNlYGnn0Nil2KOdm1ZfD0Vnqyv7B5Ov0NSjWyRd6qlU0orEfcR4IeLeuBKM0_It89RepEU9ci4nnBIsf8KLCJ0RwVrT6M", 10 | "q": "xbURQBsHoHwhD9lrQL3fD5FjCCKnvMFG1OkgY-_v-Wohu9r5ezsU0ZDwfdRPp0LvbTLdb0JRoLXcV9Abn0CmeQyPD9xfyToFQyHA1DfIVy5TheKZnjT8Y4UZg-S05LxA_yhjF19H1A78usT5IJq5l6mmHbr_UeC_DrETQXEruQ8" 11 | } -------------------------------------------------------------------------------- /x509util/testdata/capath/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBdTCCARygAwIBAgIRAMzIwp8pYDKH01yvNcwKLqYwCgYIKoZIzj0EAwIwGTEX 3 | MBUGA1UEAxMOU21hbGxzdGVwIENBIDEwHhcNMjEwNDE0MDEyNzMwWhcNMzEwNDEy 4 | MDEyNzMwWjAZMRcwFQYDVQQDEw5TbWFsbHN0ZXAgQ0EgMTBZMBMGByqGSM49AgEG 5 | CCqGSM49AwEHA0IABPKwI/NGpH5uWYH9KYrusC3aszBIxin+mDFSt7sJiPjfkHps 6 | l8HPUWrUvjz0BuHm0ic52zCHwftQc1EXFDuDxpajRTBDMA4GA1UdDwEB/wQEAwIB 7 | BjASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBTxlV+DRZS5m5HrFGf83OsG 8 | W4SYNzAKBggqhkjOPQQDAgNHADBEAiBdVZTcpwwZpfgmU6jqpO8Amn1O3ZZSHXog 9 | XWDjTaH/4gIgTaGEuNVMXoMQl/nr8lEcQtaP/p+0woHKL9JGr13ZYNI= 10 | -----END CERTIFICATE----- 11 | -----BEGIN CERTIFICATE----- 12 | MIIBdjCCARygAwIBAgIRAMhq6mlSxCy4ZfXyvlOabZEwCgYIKoZIzj0EAwIwGTEX 13 | MBUGA1UEAxMOU21hbGxzdGVwIENBIDIwHhcNMjEwNDE0MDEyNzM5WhcNMzEwNDEy 14 | MDEyNzM5WjAZMRcwFQYDVQQDEw5TbWFsbHN0ZXAgQ0EgMjBZMBMGByqGSM49AgEG 15 | CCqGSM49AwEHA0IABDPFYafdCLBSLtjXZev0PEHJpRyYhLiFUjOGx/Dxbie0LGmU 16 | fWlU8AIh7e9jjvl+ugdhco3CoWEUoBCuD9S99DujRTBDMA4GA1UdDwEB/wQEAwIB 17 | BjASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBQj++HJHgFcVIvah8WOTvMd 18 | UboxGDAKBggqhkjOPQQDAgNIADBFAiBeMmKo4n3LvQCgGF609rH/fjJbGI00ZrrS 19 | Pe9qXRrxWwIhAKBurnttPIYbOzidmrFA8fBF4w24lu0WmDOr5Cz8IfP9 20 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /jose/testdata/bad-rsa.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDODCCAiACCQC6wmhtiX91ITANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJV 3 | UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xFjAUBgNVBAoM 4 | DUV4YW1wbGUsIEluYy4xEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yMDA0MjIwMTE3 5 | NDNaFw0yMDA1MjIwMTE3NDNaMF4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEW 6 | MBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEWMBQGA1UECgwNRXhhbXBsZSwgSW5jLjES 7 | MBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC 8 | AQEA8k+4ZQO7jugI0K23YJxyCw2MD2ucWCL4RI4vmxwlFsNfy/jLqqWo1ihr+7aE 9 | CIqHoZGLs3hYJ5PkD83kFa873XGOBCQhBhN+MV3IE5V/GVT6o7c4KtLfvn9weHn7 10 | UZqOf5A8BqZ5b0H1DzWsWziY4MJIYWRBIvS5P6SEmrM3pvfQJRWK8ue7mcq8REye 11 | uzcQLCohIuH4Ea9ljXtRIUlpRKFVZ+vG6/A4agv4g1vfc1ZRg915ffRpg5bjRdJX 12 | 9uDSAJaq5+JqYLibwXkELnD8JCnTRUw3hR7xUvtqjr1Y9vZFiKHinSuluYs2S89S 13 | U0viuR2kjFflGA1K4rEFOD+7swIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBFBC0C 14 | wpD1uSOOp1VXjb0Pg3pLRRgtrN82S/6b22H0Leg+0XNcNaTI0uLMlC1dFR7koA8T 15 | Nys38jqLjufuoBXAJhKfRl4Y4WXMW2c5iHnAgk3KPurVMdNjpIxRp7Hitk4hu0R+ 16 | aqAnqJuwUp2L7f8RMS2YASR3odX5I7Qszw6zgiIWJkT793ZPBhTjQp4/ahSp/Sxy 17 | GEv2aeO1OKsLTO5CItKF7xtbHcZrgdFcHBNF+gRMT+G3AnVTtEUgkC32yyKrtvaQ 18 | kXdxA0qB0q0xEs9QoClbdrHE9oIA3pUSFMDuF5YqaidUZ7xM5YuJYw8m1ihOXaPg 19 | FTAGBZzwXRGT7Xhx 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /tpm/names.go: -------------------------------------------------------------------------------- 1 | package tpm 2 | 3 | import ( 4 | "crypto/rand" 5 | "fmt" 6 | ) 7 | 8 | // processName creates a random 10 character name if the provided 9 | // one is empty. 10 | func processName(name string) (string, error) { 11 | if name == "" { 12 | // TODO: decouple the TPM key name from the name recorded in the storage? This might 13 | // make it easier to work with the key names as a user; the TPM key name would be abstracted 14 | // away. The key name in the storage can be different from the key stored with the key (which, 15 | // to be far, isn't even used on Linux TPMs) 16 | nameHex := make([]byte, 5) 17 | if n, err := rand.Read(nameHex); err != nil || n != len(nameHex) { 18 | return "", fmt.Errorf("failed reading from CSPRNG: %w", err) 19 | } 20 | name = fmt.Sprintf("%x", nameHex) 21 | } 22 | 23 | return name, nil 24 | } 25 | 26 | // prefixAK prefixes `ak-` to the provided name. 27 | // 28 | // `ak-` is the default go-attestation uses for AKs. 29 | func prefixAK(name string) string { 30 | return fmt.Sprintf("ak-%s", name) 31 | } 32 | 33 | // prefixKey prefixes `app-` to the provided name. 34 | // 35 | // `app-` is the default that go-attestation uses for Keys. 36 | func prefixKey(name string) string { 37 | return fmt.Sprintf("app-%s", name) 38 | } 39 | -------------------------------------------------------------------------------- /fipsutil/fipsutil.go: -------------------------------------------------------------------------------- 1 | //go:build go1.24 2 | 3 | package fipsutil 4 | 5 | import ( 6 | "crypto/fips140" 7 | "os" 8 | "strings" 9 | "sync" 10 | ) 11 | 12 | var ( 13 | only bool 14 | once sync.Once 15 | ) 16 | 17 | // Enabled reports whether the cryptography libraries are operating in FIPS 18 | // 140-3 mode. 19 | // 20 | // It can be controlled at runtime using the GODEBUG setting "fips140". If set 21 | // to "on", FIPS 140-3 mode is enabled. If set to "only", non-approved 22 | // cryptography functions will additionally return errors or panic. 23 | // 24 | // This can't be changed after the program has started. 25 | func Enabled() bool { 26 | return fips140.Enabled() 27 | } 28 | 29 | // Only reports whether the cryptography libraries are operating in FIPS 140-3 30 | // "only" mode. When in this mode, using non-approved cryptography functions 31 | // will return errors or panic. 32 | func Only() bool { 33 | once.Do(func() { 34 | if !fips140.Enabled() { 35 | return 36 | } 37 | 38 | // Parse GODEBUG backwards as the last value is the correct one. 39 | settings := strings.Split(os.Getenv("GODEBUG"), ",") 40 | for i := len(settings) - 1; i >= 0; i-- { 41 | if settings[i] == "fips140=only" { 42 | only = true 43 | return 44 | } 45 | } 46 | }) 47 | 48 | return only 49 | } 50 | -------------------------------------------------------------------------------- /tpm/storage/blackhole_test.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestBlackHoleContext(t *testing.T) { 11 | t.Parallel() 12 | 13 | got := BlackHoleContext(nil) //nolint:staticcheck // nil context for testing 14 | require.NotNil(t, got) 15 | require.NotNil(t, FromContext(got)) 16 | 17 | got = BlackHoleContext(context.TODO()) 18 | require.NotNil(t, got) 19 | require.NotNil(t, FromContext(got)) 20 | } 21 | 22 | func TestBlackHole(t *testing.T) { 23 | t.Parallel() 24 | 25 | store := BlackHole() 26 | err := store.AddAK(&AK{Name: "ak"}) 27 | require.ErrorIs(t, err, ErrNoStorageConfigured) 28 | 29 | k, err := store.GetAK("ak") 30 | require.ErrorIs(t, err, ErrNoStorageConfigured) 31 | require.Nil(t, k) 32 | 33 | err = store.UpdateAK(k) 34 | require.ErrorIs(t, err, ErrNoStorageConfigured) 35 | 36 | names := store.ListAKNames() 37 | require.Empty(t, names) 38 | 39 | aks, err := store.ListAKs() 40 | require.ErrorIs(t, err, ErrNoStorageConfigured) 41 | require.Empty(t, aks) 42 | 43 | err = store.DeleteAK("ak") 44 | require.ErrorIs(t, err, ErrNoStorageConfigured) 45 | 46 | err = store.Persist() 47 | require.NoError(t, err) 48 | 49 | err = store.Load() 50 | require.NoError(t, err) 51 | } 52 | -------------------------------------------------------------------------------- /tpm/rand/rand_simulator_test.go: -------------------------------------------------------------------------------- 1 | //go:build tpmsimulator 2 | 3 | package rand 4 | 5 | import ( 6 | "crypto/ecdsa" 7 | "crypto/elliptic" 8 | "crypto/rsa" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | "go.step.sm/crypto/tpm" 14 | "go.step.sm/crypto/tpm/simulator" 15 | ) 16 | 17 | func withSimulator(t *testing.T) tpm.NewTPMOption { 18 | t.Helper() 19 | var sim simulator.Simulator 20 | t.Cleanup(func() { 21 | if sim == nil { 22 | return 23 | } 24 | err := sim.Close() 25 | require.NoError(t, err) 26 | }) 27 | sim, err := simulator.New() 28 | require.NoError(t, err) 29 | err = sim.Open() 30 | require.NoError(t, err) 31 | return tpm.WithSimulator(sim) 32 | } 33 | 34 | func TestNew(t *testing.T) { 35 | r, err := New(withSimulator(t)) 36 | require.NoError(t, err) 37 | require.NotNil(t, r) 38 | 39 | ecdsaKey, err := ecdsa.GenerateKey(elliptic.P256(), r) 40 | require.NoError(t, err) 41 | if assert.NotNil(t, ecdsaKey) { 42 | size := (ecdsaKey.D.BitLen() + 7) / 8 43 | require.Equal(t, 32, size) 44 | } 45 | 46 | rsaKey, err := rsa.GenerateKey(r, 2048) 47 | require.NoError(t, err) 48 | if assert.NotNil(t, rsaKey) { 49 | require.Equal(t, 256, rsaKey.Size()) // 2048 bits; 256 bytes expected to have been read 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /nssdb/metadata.go: -------------------------------------------------------------------------------- 1 | package nssdb 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | ) 7 | 8 | type Metadata struct { 9 | ID string 10 | Item1 []byte 11 | Item2 []byte 12 | } 13 | 14 | type Password struct { 15 | Salt []byte 16 | EncryptedPassword []byte 17 | } 18 | 19 | // The schema of the metaData table is (id string, item1, item2) 20 | func (db *NSSDB) GetMetadata(ctx context.Context, id string) (*Metadata, error) { 21 | entry := &Metadata{ 22 | ID: id, 23 | } 24 | err := db.Key.QueryRowContext(ctx, "SELECT item1, item2 FROM metaData WHERE id = ?", id).Scan(&entry.Item1, &entry.Item2) 25 | if err != nil { 26 | return nil, fmt.Errorf("get metaData.%s: %w", id, err) 27 | } 28 | 29 | return entry, nil 30 | } 31 | 32 | func (db *NSSDB) GetPassword(ctx context.Context) (*Password, error) { 33 | meta, err := db.GetMetadata(ctx, "password") 34 | if err != nil { 35 | return nil, fmt.Errorf(`get "password" from metaData: %w`, err) 36 | } 37 | 38 | return &Password{ 39 | Salt: meta.Item1, 40 | EncryptedPassword: meta.Item2, 41 | }, nil 42 | } 43 | 44 | func (db *NSSDB) deleteSignatures(ctx context.Context, objectID uint32) error { 45 | id := keySignatureID(objectID) 46 | _, err := db.Key.ExecContext(ctx, "DELETE FROM metaData WHERE id = ?", id) 47 | return err 48 | } 49 | -------------------------------------------------------------------------------- /kms/pkcs11/yubihsm2_test.go: -------------------------------------------------------------------------------- 1 | //go:build cgo && yubihsm2 2 | 3 | package pkcs11 4 | 5 | import ( 6 | "runtime" 7 | "sync" 8 | 9 | "github.com/ThalesIgnite/crypto11" 10 | ) 11 | 12 | var yubiHSM2Once sync.Once 13 | 14 | // mustPKCS11 configures a *PKCS11 KMS to be used with YubiHSM2. To initialize 15 | // these tests, we should run: 16 | // 17 | // yubihsm-connector -d 18 | func mustPKCS11(t TBTesting) *PKCS11 { 19 | t.Helper() 20 | testModule = "YubiHSM2" 21 | if runtime.GOARCH != "amd64" { 22 | t.Skipf("yubiHSM2 test skipped on %s:%s", runtime.GOOS, runtime.GOARCH) 23 | } 24 | 25 | var path string 26 | switch runtime.GOOS { 27 | case "darwin": 28 | path = "/usr/local/lib/pkcs11/yubihsm_pkcs11.dylib" 29 | case "linux": 30 | path = "/usr/lib/x86_64-linux-gnu/pkcs11/yubihsm_pkcs11.so" 31 | default: 32 | t.Skipf("yubiHSM2 test skipped on %s", runtime.GOOS) 33 | return nil 34 | } 35 | p11, err := crypto11.Configure(&crypto11.Config{ 36 | Path: path, 37 | TokenLabel: "YubiHSM", 38 | Pin: "0001password", 39 | }) 40 | if err != nil { 41 | t.Fatalf("failed to configure YubiHSM2 on %s: %v", runtime.GOOS, err) 42 | } 43 | 44 | k := &PKCS11{ 45 | p11: p11, 46 | } 47 | 48 | // Setup 49 | yubiHSM2Once.Do(func() { 50 | teardown(t, k) 51 | setup(t, k) 52 | }) 53 | 54 | return k 55 | } 56 | -------------------------------------------------------------------------------- /tpm/tss2.go: -------------------------------------------------------------------------------- 1 | package tpm 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/google/go-tpm/tpmutil" 7 | 8 | "go.step.sm/crypto/tpm/tss2" 9 | ) 10 | 11 | const ( 12 | // Defined in "Registry of reserved TPM 2.0 handles and localities", 13 | // and checked on a glinux machine. This is the default parent handle 14 | // used by go-tpm and go-attestation, and thus also the default handle 15 | // set when marshaling to the TSS2 format. 16 | commonSrkEquivalentHandle = tpmutil.Handle(0x81000001) 17 | ) 18 | 19 | // ToTSS2 gets the public and private blobs and returns a [*tss2.TPMKey]. 20 | func (ak *AK) ToTSS2(ctx context.Context) (*tss2.TPMKey, error) { 21 | blobs, err := ak.Blobs(ctx) 22 | if err != nil { 23 | return nil, err 24 | } 25 | return tss2.New( 26 | blobs.public, 27 | blobs.private, 28 | tss2.WithParent(commonSrkEquivalentHandle), // default parent used by go-tpm/go-attestation 29 | ), nil 30 | } 31 | 32 | // ToTSS2 gets the public and private blobs and returns a [*tss2.TPMKey]. 33 | func (k *Key) ToTSS2(ctx context.Context) (*tss2.TPMKey, error) { 34 | blobs, err := k.Blobs(ctx) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return tss2.New( 39 | blobs.public, 40 | blobs.private, 41 | tss2.WithParent(commonSrkEquivalentHandle), // default parent used by go-tpm/go-attestation 42 | ), nil 43 | } 44 | -------------------------------------------------------------------------------- /tpm/manufacturer/manufacturers_test.go: -------------------------------------------------------------------------------- 1 | package manufacturer 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func Test_GetEncodings(t *testing.T) { 11 | tests := []struct { 12 | name string 13 | id ID 14 | want string 15 | }{ 16 | {"infineon", 1229346816, "IFX"}, 17 | {"intel", 1229870147, "INTC"}, 18 | {"stm", 1398033696, "STM "}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got, _ := GetEncodings(tt.id); got != tt.want { 23 | t.Errorf("GetEncodings() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | 29 | func Test_GetNameByASCII(t *testing.T) { 30 | tests := []struct { 31 | name string 32 | ascii string 33 | want string 34 | }{ 35 | {"infineon", "IFX", "Infineon"}, 36 | {"intel", "INTC", "Intel"}, 37 | {"stm", "STM ", "ST Microelectronics"}, 38 | {"unknown", "0000", "unknown"}, 39 | } 40 | for _, tt := range tests { 41 | t.Run(tt.name, func(t *testing.T) { 42 | if got := GetNameByASCII(tt.ascii); got != tt.want { 43 | t.Errorf("GetNameByASCII() = %v, want %v", got, tt.want) 44 | } 45 | }) 46 | } 47 | } 48 | 49 | func TestID_MarshalJSON(t *testing.T) { 50 | b, err := json.Marshal(ID(12345678)) 51 | require.NoError(t, err) 52 | require.JSONEq(t, `"12345678"`, string(b)) 53 | } 54 | -------------------------------------------------------------------------------- /x509util/certpool.go: -------------------------------------------------------------------------------- 1 | package x509util 2 | 3 | import ( 4 | "crypto/x509" 5 | "os" 6 | "path/filepath" 7 | "strings" 8 | 9 | "github.com/pkg/errors" 10 | ) 11 | 12 | // ReadCertPool loads a certificate pool from disk. The given path can be a 13 | // file, a directory, or a comma-separated list of files. 14 | func ReadCertPool(path string) (*x509.CertPool, error) { 15 | info, err := os.Stat(path) 16 | if err != nil && !os.IsNotExist(err) { 17 | return nil, errors.Wrap(err, "error reading cert pool") 18 | } 19 | 20 | var ( 21 | files []string 22 | pool = x509.NewCertPool() 23 | ) 24 | if info != nil && info.IsDir() { 25 | finfos, err := os.ReadDir(path) 26 | if err != nil { 27 | return nil, errors.Wrap(err, "error reading cert pool") 28 | } 29 | for _, finfo := range finfos { 30 | files = append(files, filepath.Join(path, finfo.Name())) 31 | } 32 | } else { 33 | files = strings.Split(path, ",") 34 | for i := range files { 35 | files[i] = strings.TrimSpace(files[i]) 36 | } 37 | } 38 | 39 | var found bool 40 | for _, f := range files { 41 | bytes, err := os.ReadFile(f) 42 | if err != nil { 43 | return nil, errors.Wrap(err, "error reading cert pool") 44 | } 45 | if ok := pool.AppendCertsFromPEM(bytes); ok { 46 | found = true 47 | } 48 | } 49 | if !found { 50 | return nil, errors.New("error reading cert pool: not certificates found") 51 | } 52 | return pool, nil 53 | } 54 | -------------------------------------------------------------------------------- /x509util/testdata/letsencrypt.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIID1DCCA1qgAwIBAgISA7NpNuqAqIBOmvpNUK3sJ3ZfMAoGCCqGSM49BAMDMDIx 3 | CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF 4 | NjAeFw0yNTAyMDUxMzU0MDFaFw0yNTA1MDYxMzU0MDBaMBoxGDAWBgNVBAMTD2xl 5 | dHNlbmNyeXB0Lm9yZzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFMtO1UPccGh 6 | Sc22brM9UZ0iQBrOTA591YIbOYIMjcRosUr1QvUCU6qytEG05I2Q+q3/7CuKWJWM 7 | YBrpngAneh+jggJmMIICYjAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYB 8 | BQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFI8WiTHls/Xf 9 | jkRIel9K6z5hu6g+MB8GA1UdIwQYMBaAFJMnRpgDqVFojpjWxEJI2yO/WJTSMFUG 10 | CCsGAQUFBwEBBEkwRzAhBggrBgEFBQcwAYYVaHR0cDovL2U2Lm8ubGVuY3Iub3Jn 11 | MCIGCCsGAQUFBzAChhZodHRwOi8vZTYuaS5sZW5jci5vcmcvMG8GA1UdEQRoMGaC 12 | CWxlbmNyLm9yZ4IPbGV0c2VuY3J5cHQuY29tgg9sZXRzZW5jcnlwdC5vcmeCDXd3 13 | dy5sZW5jci5vcmeCE3d3dy5sZXRzZW5jcnlwdC5jb22CE3d3dy5sZXRzZW5jcnlw 14 | dC5vcmcwEwYDVR0gBAwwCjAIBgZngQwBAgEwggEEBgorBgEEAdZ5AgQCBIH1BIHy 15 | APAAdgDM+w9qhXEJZf6Vm1PO6bJ8IumFXA2XjbapflTA/kwNsAAAAZTWmTBDAAAE 16 | AwBHMEUCIQC3rNgMmSLcU0QEirE7KRJJUNvPdTfGYovR+9DKfQ6nRQIgBRCe7Pkb 17 | /1Jbdjs2b3WveDO7gXEIeh180dTRyTyJWfcAdgDgkrP8DB3I52g2H95huZZNClJ4 18 | GYpy1nLEsE2lbW9UBAAAAZTWmTAtAAAEAwBHMEUCIFzFrg1ekuosIsD2iN/xWGpu 19 | +F1lrVUT11937GsIGfUSAiEA2ZUliRQ9+0DQoozWE2ynI4CmnZ6V5qYTSLczPBMu 20 | yLAwCgYIKoZIzj0EAwMDaAAwZQIxAMS9K8+IQbIIfLoVJRPgIvI3MRVmR1CuGUmr 21 | Jwu4+my9nOMcVXmgL+wVaBB2iE/MMQIwdZIKNllOWwM2NeXbgnjERy3+1ytbMVAf 22 | t0cHSdM2e7EH2MJuSg5fhFhg07MAboJJ 23 | -----END CERTIFICATE----- 24 | -------------------------------------------------------------------------------- /internal/bcrypt_pbkdf/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Dmitry Chestnykh 2 | Copyright (c) 2010 The Go Authors 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above 13 | copyright notice, this list of conditions and the following 14 | disclaimer in the documentation and/or other materials 15 | provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /kms/tpmkms/uri_test.go: -------------------------------------------------------------------------------- 1 | package tpmkms 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func Test_parseNameURI(t *testing.T) { 10 | type args struct { 11 | nameURI string 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | wantO objectProperties 17 | wantErr bool 18 | }{ 19 | {"ok/key-without-scheme", args{"key1"}, objectProperties{name: "key1"}, false}, 20 | {"ok/key", args{"tpmkms:name=key1"}, objectProperties{name: "key1"}, false}, 21 | {"ok/key-without-name-key", args{"tpmkms:key1"}, objectProperties{name: "key1"}, false}, 22 | {"ok/key-without-name-key-with-other-properties", args{"tpmkms:key1;attest-by=ak1"}, objectProperties{name: "key1", attestBy: "ak1"}, false}, 23 | {"ok/attested-key", args{"tpmkms:name=key2;attest-by=ak1;qualifying-data=61626364"}, objectProperties{name: "key2", attestBy: "ak1", qualifyingData: []byte{'a', 'b', 'c', 'd'}}, false}, 24 | {"ok/ak", args{"tpmkms:name=ak1;ak=true"}, objectProperties{name: "ak1", ak: true}, false}, 25 | {"fail/empty", args{""}, objectProperties{}, true}, 26 | {"fail/wrong-scheme", args{nameURI: "tpmkmz:name=bla"}, objectProperties{}, true}, 27 | } 28 | for _, tt := range tests { 29 | t.Run(tt.name, func(t *testing.T) { 30 | gotO, err := parseNameURI(tt.args.nameURI) 31 | if tt.wantErr { 32 | assert.Error(t, err) 33 | return 34 | } 35 | 36 | assert.NoError(t, err) 37 | assert.Equal(t, tt.wantO, gotO) 38 | }) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /kms/pkcs11/softhsm2_test.go: -------------------------------------------------------------------------------- 1 | //go:build cgo && softhsm2 2 | 3 | package pkcs11 4 | 5 | import ( 6 | "runtime" 7 | "sync" 8 | 9 | "github.com/ThalesIgnite/crypto11" 10 | ) 11 | 12 | var softHSM2Once sync.Once 13 | 14 | // mustPKCS11 configures a *PKCS11 KMS to be used with SoftHSM2. To initialize 15 | // these tests, we should run: 16 | // 17 | // softhsm2-util --init-token --free \ 18 | // --token pkcs11-test --label pkcs11-test \ 19 | // --so-pin password --pin password 20 | // 21 | // To delete we should run: 22 | // 23 | // softhsm2-util --delete-token --token pkcs11-test 24 | func mustPKCS11(t TBTesting) *PKCS11 { 25 | t.Helper() 26 | testModule = "SoftHSM2" 27 | if runtime.GOARCH != "amd64" { 28 | t.Fatalf("softHSM2 test skipped on %s:%s", runtime.GOOS, runtime.GOARCH) 29 | } 30 | 31 | var path string 32 | switch runtime.GOOS { 33 | case "darwin": 34 | path = "/usr/local/lib/softhsm/libsofthsm2.so" 35 | case "linux": 36 | path = "/usr/lib/softhsm/libsofthsm2.so" 37 | default: 38 | t.Skipf("softHSM2 test skipped on %s", runtime.GOOS) 39 | return nil 40 | } 41 | p11, err := crypto11.Configure(&crypto11.Config{ 42 | Path: path, 43 | TokenLabel: "pkcs11-test", 44 | Pin: "password", 45 | }) 46 | if err != nil { 47 | t.Fatalf("failed to configure softHSM2 on %s: %v", runtime.GOOS, err) 48 | } 49 | 50 | k := &PKCS11{ 51 | p11: p11, 52 | } 53 | 54 | // Setup 55 | softHSM2Once.Do(func() { 56 | teardown(t, k) 57 | setup(t, k) 58 | }) 59 | 60 | return k 61 | } 62 | -------------------------------------------------------------------------------- /tpm/blobs.go: -------------------------------------------------------------------------------- 1 | package tpm 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | 7 | "github.com/google/go-tpm/tpmutil" 8 | ) 9 | 10 | // Blobs is a container for the private and public blobs of data 11 | // that represent a TPM2 object. 12 | type Blobs struct { 13 | private []byte 14 | public []byte 15 | } 16 | 17 | // Private returns the private data blob of a TPM2 object including 18 | // a 16-bit header. The blob can be used with tpm2-tools. 19 | func (b *Blobs) Private() (blob []byte, err error) { 20 | if blob, err = toTPM2Tools(b.private); err != nil { 21 | return nil, fmt.Errorf("failed transforming private blob bytes: %w", err) 22 | } 23 | return 24 | } 25 | 26 | // Public returns the public data blob of a TPM2 object including 27 | // a 16-bit header. The blob can be used with tpm2-tools. 28 | func (b *Blobs) Public() (blob []byte, err error) { 29 | if blob, err = toTPM2Tools(b.public); err != nil { 30 | return nil, fmt.Errorf("failed transforming public blob bytes: %w", err) 31 | } 32 | return 33 | } 34 | 35 | func toTPM2Tools(blob []byte) ([]byte, error) { 36 | var buf bytes.Buffer 37 | bytesWithHeader := tpmutil.U16Bytes(blob) 38 | if err := bytesWithHeader.TPMMarshal(&buf); err != nil { 39 | return nil, err 40 | } 41 | return buf.Bytes(), nil 42 | } 43 | 44 | func (ak *AK) setBlobs(private, public []byte) { 45 | ak.blobs = &Blobs{ 46 | private: private, 47 | public: public, 48 | } 49 | } 50 | 51 | func (k *Key) setBlobs(private, public []byte) { 52 | k.blobs = &Blobs{ 53 | private: private, 54 | public: public, 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /kms/pkcs11/opensc_test.go: -------------------------------------------------------------------------------- 1 | //go:build opensc 2 | 3 | package pkcs11 4 | 5 | import ( 6 | "runtime" 7 | "sync" 8 | 9 | "github.com/ThalesIgnite/crypto11" 10 | ) 11 | 12 | var softHSM2Once sync.Once 13 | 14 | // mustPKCS11 configures a *PKCS11 KMS to be used with OpenSC, using for example 15 | // a Nitrokey HSM. To initialize these tests we should run: 16 | // 17 | // sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 123456 18 | // 19 | // Or: 20 | // 21 | // pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so \ 22 | // --init-token --init-pin \ 23 | // --so-pin=3537363231383830 --new-pin=123456 --pin=123456 \ 24 | // --label="pkcs11-test" 25 | func mustPKCS11(t TBTesting) *PKCS11 { 26 | t.Helper() 27 | testModule = "OpenSC" 28 | if runtime.GOARCH != "amd64" { 29 | t.Fatalf("opensc test skipped on %s:%s", runtime.GOOS, runtime.GOARCH) 30 | } 31 | 32 | var path string 33 | switch runtime.GOOS { 34 | case "darwin": 35 | path = "/usr/local/lib/opensc-pkcs11.so" 36 | case "linux": 37 | path = "/usr/local/lib/opensc-pkcs11.so" 38 | default: 39 | t.Skipf("opensc test skipped on %s", runtime.GOOS) 40 | return nil 41 | } 42 | var zero int 43 | p11, err := crypto11.Configure(&crypto11.Config{ 44 | Path: path, 45 | SlotNumber: &zero, 46 | Pin: "123456", 47 | }) 48 | if err != nil { 49 | t.Fatalf("failed to configure opensc on %s: %v", runtime.GOOS, err) 50 | } 51 | 52 | k := &PKCS11{ 53 | p11: p11, 54 | } 55 | 56 | // Setup 57 | softHSM2Once.Do(func() { 58 | teardown(t, k) 59 | setup(t, k) 60 | }) 61 | 62 | return k 63 | } 64 | -------------------------------------------------------------------------------- /x509util/testdata/fullsimple.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "subject": "subjectCommonName", 4 | "issuer": "issuerCommonName", 5 | "serialNumber": "0x1234567890", 6 | "dnsNames": "doe.com", 7 | "emailAddresses": "jane@doe.com", 8 | "ipAddresses": "127.0.0.1", 9 | "uris": "https://doe.com", 10 | "sans": [{"type":"dns", "value":"www.doe.com"}], 11 | "notBefore": "2009-02-13T23:31:30Z", 12 | "notAfter": "2009-02-14T23:31:30Z", 13 | "extensions": [{"id":"1.2.3.4","critical":true,"value":"ZXh0ZW5zaW9u"}], 14 | "keyUsage": ["digitalSignature"], 15 | "extKeyUsage": ["serverAuth"], 16 | "unknownExtKeyUsage": ["1.3.6.1.4.1.44924.1.6", "1.3.6.1.4.1.44924.1.7"], 17 | "subjectKeyId": "c3ViamVjdEtleUlk", 18 | "authorityKeyId": "YXV0aG9yaXR5S2V5SWQ=", 19 | "ocspServer": "https://ocsp.server", 20 | "issuingCertificateURL": "https://ca.com", 21 | "crlDistributionPoints": "https://ca.com/ca.crl", 22 | "policyIdentifiers": "1.2.3.4.5.6", 23 | "basicConstraints": { 24 | "isCA": false, 25 | "maxPathLen": 0 26 | }, 27 | "nameConstraints": { 28 | "critical": true, 29 | "permittedDNSDomains": "jane.doe.com", 30 | "excludedDNSDomains": "john.doe.com", 31 | "permittedIPRanges": "127.0.0.1/32", 32 | "excludedIPRanges": "0.0.0.0/0", 33 | "permittedEmailAddresses": "jane@doe.com", 34 | "excludedEmailAddresses": "john@doe.com", 35 | "permittedURIDomains": "https://jane.doe.com", 36 | "excludedURIDomains": "https://john.doe.com" 37 | }, 38 | "signatureAlgorithm": "Ed25519" 39 | } -------------------------------------------------------------------------------- /kms/kms.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/pkg/errors" 7 | "go.step.sm/crypto/kms/apiv1" 8 | 9 | // Enable default implementation 10 | "go.step.sm/crypto/kms/softkms" 11 | ) 12 | 13 | // KeyManager is the interface implemented by all the KMS. 14 | type KeyManager = apiv1.KeyManager 15 | 16 | // CertificateManager is the interface implemented by the KMS that can load and 17 | // store x509.Certificates. 18 | type CertificateManager = apiv1.CertificateManager 19 | 20 | // Attester is the interface implemented by the KMS that can respond with an 21 | // attestation certificate or key. 22 | // 23 | // # Experimental 24 | // 25 | // Notice: This API is EXPERIMENTAL and may be changed or removed in a later 26 | // release. 27 | type Attester = apiv1.Attester 28 | 29 | // Options are the KMS options. They represent the kms object in the ca.json. 30 | type Options = apiv1.Options 31 | 32 | // Type represents the KMS type used. 33 | type Type = apiv1.Type 34 | 35 | // TypeOf returns the KMS type of the given uri. 36 | var TypeOf = apiv1.TypeOf 37 | 38 | // Default is the implementation of the default KMS. 39 | var Default = &softkms.SoftKMS{} 40 | 41 | // New initializes a new KMS from the given type. 42 | func New(ctx context.Context, opts apiv1.Options) (KeyManager, error) { 43 | if err := opts.Validate(); err != nil { 44 | return nil, err 45 | } 46 | 47 | typ, err := opts.GetType() 48 | if err != nil { 49 | return nil, err 50 | } 51 | fn, ok := apiv1.LoadKeyManagerNewFunc(typ) 52 | if !ok { 53 | return nil, errors.Errorf("unsupported kms type '%s'", typ) 54 | } 55 | return fn(ctx, opts) 56 | } 57 | -------------------------------------------------------------------------------- /kms/object.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import ( 4 | "bytes" 5 | "encoding/pem" 6 | "io" 7 | "io/fs" 8 | "sync" 9 | "time" 10 | 11 | "go.step.sm/crypto/pemutil" 12 | ) 13 | 14 | // object implements the fs.File and fs.FileMode interfaces. 15 | type object struct { 16 | Path string 17 | Object interface{} 18 | once sync.Once 19 | err error 20 | pemData *bytes.Buffer 21 | } 22 | 23 | // FileMode implementation 24 | func (o *object) Name() string { return o.Path } 25 | func (o *object) Size() int64 { return int64(o.pemData.Len()) } 26 | func (o *object) Mode() fs.FileMode { return 0400 } 27 | func (o *object) ModTime() time.Time { return time.Time{} } 28 | func (o *object) IsDir() bool { return false } 29 | func (o *object) Sys() interface{} { return o.Object } 30 | 31 | func (o *object) load() error { 32 | o.once.Do(func() { 33 | b, err := pemutil.Serialize(o.Object) 34 | if err != nil { 35 | o.err = &fs.PathError{ 36 | Op: "open", 37 | Path: o.Path, 38 | Err: err, 39 | } 40 | return 41 | } 42 | o.pemData = bytes.NewBuffer(pem.EncodeToMemory(b)) 43 | }) 44 | return o.err 45 | } 46 | 47 | func (o *object) Stat() (fs.FileInfo, error) { 48 | if err := o.load(); err != nil { 49 | return nil, err 50 | } 51 | return o, nil 52 | } 53 | 54 | func (o *object) Read(b []byte) (int, error) { 55 | if err := o.load(); err != nil { 56 | return 0, err 57 | } 58 | return o.pemData.Read(b) 59 | } 60 | 61 | func (o *object) Close() error { 62 | o.Object = nil 63 | o.pemData = nil 64 | if o.err == nil { 65 | o.err = io.EOF 66 | return nil 67 | } 68 | return o.err 69 | } 70 | -------------------------------------------------------------------------------- /nssdb/object.go: -------------------------------------------------------------------------------- 1 | package nssdb 2 | 3 | import ( 4 | "bytes" 5 | "encoding/hex" 6 | "fmt" 7 | ) 8 | 9 | // Object is an entry in nssPublic or nssPrivate plus any related entries in 10 | // the metaData table. The encoding for and meaning of most attributes can be 11 | // found in the PKCS #11 spec. 12 | type Object struct { 13 | ID uint32 14 | Attributes map[string][]byte 15 | ULongAttributes map[string]uint32 16 | EncryptedAttributes map[string][]byte 17 | Metadata []*Metadata 18 | } 19 | 20 | func (obj *Object) Print() { 21 | fmt.Printf("ID: %d\n", obj.ID) 22 | 23 | for k, data := range obj.EncryptedAttributes { 24 | fmt.Printf("%s (encrypted): %x\n", k, data) 25 | } 26 | 27 | for _, meta := range obj.Metadata { 28 | fmt.Printf("%s: %x\n", meta.ID, meta.Item1) 29 | } 30 | 31 | for k, u := range obj.ULongAttributes { 32 | fmt.Printf("%s: %d\n", k, u) 33 | } 34 | 35 | for k, data := range obj.Attributes { 36 | fmt.Printf("%s: %x\n", k, data) 37 | } 38 | } 39 | 40 | func (obj Object) ValidateULong(name string, want uint32) error { 41 | attr, ok := obj.ULongAttributes[name] 42 | if !ok { 43 | return fmt.Errorf("object is missing attribute %s", name) 44 | } 45 | if attr != want { 46 | return fmt.Errorf("%s expected %d but got %d", name, attr, want) 47 | } 48 | return nil 49 | } 50 | 51 | func (obj Object) Validate(name string, want []byte) error { 52 | attr, ok := obj.Attributes[name] 53 | if !ok { 54 | return fmt.Errorf("object is missing attribute %s", name) 55 | } 56 | if !bytes.Equal(attr, want) { 57 | return fmt.Errorf("%s has value %q, expected %q", name, hex.EncodeToString(attr), hex.EncodeToString(want)) 58 | } 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /tpm/attestation/requestid.go: -------------------------------------------------------------------------------- 1 | package attestation 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | 7 | "go.step.sm/crypto/randutil" 8 | ) 9 | 10 | type requestIDContextKey struct{} 11 | 12 | // NewRequestIDContext returns a new context with the given request ID added to the 13 | // context. 14 | func NewRequestIDContext(ctx context.Context, requestID string) context.Context { 15 | return context.WithValue(ctx, requestIDContextKey{}, requestID) 16 | } 17 | 18 | // RequestIDFromContext returns the request ID from the context if it exists. 19 | // and is not empty. 20 | func RequestIDFromContext(ctx context.Context) (string, bool) { 21 | v, ok := ctx.Value(requestIDContextKey{}).(string) 22 | return v, ok && v != "" 23 | } 24 | 25 | // requestIDHeader is the header name used for propagating request IDs from 26 | // the attestation client to the attestation CA and back again. 27 | const requestIDHeader = "X-Request-Id" 28 | 29 | // newRequestID generates a new random UUIDv4 request ID. If it fails, 30 | // the request ID will be the empty string. 31 | func newRequestID() string { 32 | requestID, err := randutil.UUIDv4() 33 | if err != nil { 34 | return "" 35 | } 36 | 37 | return requestID 38 | } 39 | 40 | // enforceRequestID checks if the X-Request-Id HTTP header is filled. If it's 41 | // empty, the context is searched for a request ID. If that's also empty, a new 42 | // request ID is generated. 43 | func enforceRequestID(r *http.Request) { 44 | if requestID := r.Header.Get(requestIDHeader); requestID == "" { 45 | if reqID, ok := RequestIDFromContext(r.Context()); ok { 46 | requestID = reqID 47 | } else { 48 | requestID = newRequestID() 49 | } 50 | r.Header.Set(requestIDHeader, requestID) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | title: "[Bug]: " 4 | labels: ["bug", "needs triage"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this bug report! 10 | - type: textarea 11 | id: steps 12 | attributes: 13 | label: Steps to Reproduce 14 | description: Tell us how to reproduce this issue. 15 | placeholder: These are the steps! 16 | validations: 17 | required: true 18 | - type: textarea 19 | id: your-env 20 | attributes: 21 | label: Your Environment 22 | value: |- 23 | * OS - 24 | * Version - 25 | validations: 26 | required: true 27 | - type: textarea 28 | id: expected-behavior 29 | attributes: 30 | label: Expected Behavior 31 | description: What did you expect to happen? 32 | validations: 33 | required: true 34 | - type: textarea 35 | id: actual-behavior 36 | attributes: 37 | label: Actual Behavior 38 | description: What happens instead? 39 | validations: 40 | required: true 41 | - type: textarea 42 | id: context 43 | attributes: 44 | label: Additional Context 45 | description: Add any other context about the problem here. 46 | validations: 47 | required: false 48 | - type: textarea 49 | id: contributing 50 | attributes: 51 | label: Contributing 52 | value: | 53 | Vote on this issue by adding a 👍 reaction. 54 | To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already). 55 | validations: 56 | required: false 57 | -------------------------------------------------------------------------------- /kms/azurekms/lazy_client.go: -------------------------------------------------------------------------------- 1 | //go:build !noazurekms 2 | 3 | package azurekms 4 | 5 | import ( 6 | "fmt" 7 | "sync" 8 | 9 | "github.com/Azure/azure-sdk-for-go/sdk/azcore" 10 | "github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys" 11 | ) 12 | 13 | type lazyClientFunc func(vaultURL string) (KeyVaultClient, error) 14 | 15 | type lazyClient struct { 16 | rw sync.RWMutex 17 | clients map[string]KeyVaultClient 18 | new lazyClientFunc 19 | dnsSuffix string 20 | } 21 | 22 | func newLazyClient(dnsSuffix string, fn lazyClientFunc) *lazyClient { 23 | return &lazyClient{ 24 | clients: make(map[string]KeyVaultClient), 25 | new: fn, 26 | dnsSuffix: dnsSuffix, 27 | } 28 | } 29 | 30 | func (l *lazyClient) Get(vault string) (KeyVaultClient, error) { 31 | vaultURL := vaultBaseURL(vault, l.dnsSuffix) 32 | // Get an already initialize client 33 | l.rw.RLock() 34 | c, ok := l.clients[vaultURL] 35 | l.rw.RUnlock() 36 | if ok { 37 | return c, nil 38 | } 39 | 40 | // Create a new client 41 | c, err := l.new(vaultURL) 42 | if err != nil { 43 | return nil, fmt.Errorf("error creating client for vault %q: %w", vaultURL, err) 44 | } 45 | 46 | l.rw.Lock() 47 | l.clients[vaultURL] = c 48 | l.rw.Unlock() 49 | return c, nil 50 | } 51 | 52 | func lazyClientCreator(credential azcore.TokenCredential) lazyClientFunc { 53 | return func(vaultURL string) (KeyVaultClient, error) { 54 | return azkeys.NewClient(vaultURL, credential, &azkeys.ClientOptions{ 55 | // See https://aka.ms/azsdk/blog/vault-uri 56 | DisableChallengeResourceVerification: true, 57 | }) 58 | } 59 | } 60 | 61 | func vaultBaseURL(vault, dnsSuffix string) string { 62 | return "https://" + vault + "." + dnsSuffix + "/" 63 | } 64 | -------------------------------------------------------------------------------- /pemutil/testdata/bundle-1st.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEhzCCA2+gAwIBAgISA78mVnMzLbLQxw5IoWP7fRG6MA0GCSqGSIb3DQEBCwUA 3 | MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD 4 | ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xOTAyMDgxMzA3NDRaFw0x 5 | OTA1MDkxMzA3NDRaMBgxFjAUBgNVBAMTDXNtYWxsc3RlcC5jb20wWTATBgcqhkjO 6 | PQIBBggqhkjOPQMBBwNCAATtaDvEhLijnzgpf/svy2v0lA0q1KNMmKmb8kdIgFsi 7 | Rqmzh0IPldiprW6/zIBPKC3ZWBzdw06ZuSXeuPQ0rcC1o4ICYjCCAl4wDgYDVR0P 8 | AQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB 9 | Af8EAjAAMB0GA1UdDgQWBBQ5p9apFolkDFuITyFnBK4BxE67dDAfBgNVHSMEGDAW 10 | gBSoSmpjBH3duubRObemRWXv86jsoTBvBggrBgEFBQcBAQRjMGEwLgYIKwYBBQUH 11 | MAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRzZW5jcnlwdC5vcmcwLwYIKwYBBQUH 12 | MAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlwdC5vcmcvMBgGA1UdEQQR 13 | MA+CDXNtYWxsc3RlcC5jb20wTAYDVR0gBEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC 14 | 3xMBAQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcw 15 | ggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdQB0ftqDMa0zEJEhnM4lT0Jwwr/9XkIg 16 | CMY3NXnmEHvMVgAAAWjNb4RTAAAEAwBGMEQCID7NdufkWtiID0FJKcXBiUnhW1OX 17 | w2eU1ZRsitnaRqL3AiBlGOiUaaWf92NGqlEkEp2/oaED0OZYbLe1LTvPnRsQoAB3 18 | AGPy283oO8wszwtyhCdXazOkjWF3j711pjixx2hUS9iNAAABaM1vhI4AAAQDAEgw 19 | RgIhAJ8A7OHfNThbzUOiSk5Y+JOSvOiSJ1ferIOX4z3AbD7qAiEA3Aiw5ZfrXyEn 20 | PsHWofgMuz8dWvv4QxFXxLZRmXH0QDIwDQYJKoZIhvcNAQELBQADggEBAFrmkLMe 21 | OhGGuOSkY3hsUnSEUy5N1lrpGRrwyWVHTPcLJdlds5S8l5xYg2LcPfWQXkUHUYcr 22 | Fo7jT5Up4UIXYvE6Lctm48geIExlQwcOkSo3ULSQJYz9bp1tDpv9cQgyHJtwfrbR 23 | 2rxtpasLIs8znzbBcJlQ4rlodyzUMEJh8YgT9XpynDbk5K43nfsng1uRqI9J6brt 24 | AasWcqPaJ97ILTT3DNtk2cLBpAqtMwaxcROdZ1104fbWzYjGgv67W78CBgndhvbp 25 | Yx8h05Bm4vY0tz7Zv0Qd3YwFKgIZQI/BR/Mdber9P+xYU51T6xu4p4JDcQsCxtYg 26 | 9zBQ7U7V9X22RGo= 27 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /pemutil/testdata/bundle-2nd.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/ 3 | MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT 4 | DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow 5 | SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT 6 | GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC 7 | AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF 8 | q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8 9 | SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0 10 | Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA 11 | a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj 12 | /PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T 13 | AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG 14 | CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv 15 | bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k 16 | c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw 17 | VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC 18 | ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz 19 | MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu 20 | Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF 21 | AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo 22 | uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/ 23 | wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu 24 | X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG 25 | PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 26 | KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== 27 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /kms/apiv1/requests_test.go: -------------------------------------------------------------------------------- 1 | package apiv1 2 | 3 | import "testing" 4 | 5 | func TestProtectionLevel_String(t *testing.T) { 6 | tests := []struct { 7 | name string 8 | p ProtectionLevel 9 | want string 10 | }{ 11 | {"unspecified", UnspecifiedProtectionLevel, "unspecified"}, 12 | {"software", Software, "software"}, 13 | {"hsm", HSM, "hsm"}, 14 | {"unknown", ProtectionLevel(100), "unknown(100)"}, 15 | } 16 | for _, tt := range tests { 17 | t.Run(tt.name, func(t *testing.T) { 18 | if got := tt.p.String(); got != tt.want { 19 | t.Errorf("ProtectionLevel.String() = %v, want %v", got, tt.want) 20 | } 21 | }) 22 | } 23 | } 24 | 25 | func TestSignatureAlgorithm_String(t *testing.T) { 26 | tests := []struct { 27 | name string 28 | s SignatureAlgorithm 29 | want string 30 | }{ 31 | {"UnspecifiedSignAlgorithm", UnspecifiedSignAlgorithm, "unspecified"}, 32 | {"SHA256WithRSA", SHA256WithRSA, "SHA256-RSA"}, 33 | {"SHA384WithRSA", SHA384WithRSA, "SHA384-RSA"}, 34 | {"SHA512WithRSA", SHA512WithRSA, "SHA512-RSA"}, 35 | {"SHA256WithRSAPSS", SHA256WithRSAPSS, "SHA256-RSAPSS"}, 36 | {"SHA384WithRSAPSS", SHA384WithRSAPSS, "SHA384-RSAPSS"}, 37 | {"SHA512WithRSAPSS", SHA512WithRSAPSS, "SHA512-RSAPSS"}, 38 | {"ECDSAWithSHA256", ECDSAWithSHA256, "ECDSA-SHA256"}, 39 | {"ECDSAWithSHA384", ECDSAWithSHA384, "ECDSA-SHA384"}, 40 | {"ECDSAWithSHA512", ECDSAWithSHA512, "ECDSA-SHA512"}, 41 | {"PureEd25519", PureEd25519, "Ed25519"}, 42 | {"unknown", SignatureAlgorithm(100), "unknown(100)"}, 43 | } 44 | for _, tt := range tests { 45 | t.Run(tt.name, func(t *testing.T) { 46 | if got := tt.s.String(); got != tt.want { 47 | t.Errorf("SignatureAlgorithm.String() = %v, want %v", got, tt.want) 48 | } 49 | }) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /x509util/testdata/rsa.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEAyl+ygIYmcdBaB33yVppREFP8/8IXeUqROKKW7gwdmrXYBuAp 3 | 7krh1oWD9fiXW+bzfvAyRBfXRZf2UTHIE9dDqAwK1vA5TJo1uGGlYFPfHikFVlbp 4 | lOyv3kVNaMwKxltPiwoAj0OjhKBjNmhE39nWsP3mJrjqom2v3ickrmkkKJ+imfSf 5 | iJmXRzPrc07l53Z8W6x9N3v+5dx6ssi38sEJVIfc6zRd4UHNW+PkeYAetjOO4gwz 6 | ss1wLzSXINJOMHl03Kdxfn/8oWUFymNhtMN/uJf582L2CpakBCRuUkCWiRRzMORU 7 | Azy+U84v4HSkSBuLmWrqaZJpTBaDQbJm/phVIQIDAQABAoIBACmOsUc3RRnGIVa8 8 | hFFIazEhLikPIGbl6yBoMvo7PrEQeoYe7j1i3zGARXLzU5GpwYLlrEzTYH+IDyrp 9 | QB7i65/MqUUuG3YhjLqKQr2fO4gkAFaUjm7ok8zfCmBk1imZgqIYsbi5uRB5JyZ7 10 | Dvmw8Cd0XBjDjFtCjwTdoOi36pb0ozSkukfYHYWbEErdBvllaMdsdtrilV/RBamn 11 | uHMGjC9le/SlmJ2bm/KfixCU9y9erqzWN1COiI9ofVt6w54jH60YPZ6LnWqqQ6iZ 12 | ry03TQtU5myuEnHbZ0e6eCVdHNNKBRvR+HO1Z/0+JiG8z1vZcOoTU2YNhTNds0Ob 13 | DIFtAWkCgYEAzt6apG5FLpQPUUWhpbgVqJsJ6agVXeUZCRnFU6cvQshpdpDEAeqO 14 | XZl5zArkG0eNeg2p0ZbUSDhl5mwh+Fq7Mf25IlK3SkQNMb0JHMr/GpqgMH7CUDlC 15 | NBBNdv0W2EglFPA55fuOYcdsb37cPWv6mIKyZ0IEMlwyk9xvesb3yKsCgYEA+m/C 16 | PiBB0UAzNpRyg3B29zGkF8bEGUqZkR+gK5hS50Q4qaawLGxn2dxLUtPh+zVRi82i 17 | Lj1+QHc5lIP9ZGOFKQjbdrjd41w+8PMJ2QpcrmqXFT9uotoBvtW2oYIICEe6l9rM 18 | +AXR0xT/CdjO5f3IXjFPI8BS6vIeK0CeasgXMWMCgYEAl6InrDt/zmKMz7/Aex5y 19 | EcKDA5hHASo6racMMwMq60LHuzbl1Zm+fPFQi7W3+h76nuqA/bYXKFDesIW2aLro 20 | 1/3oxDXpUDCNk1XC5i4Ny8xneuSPPgqacls4zO0635ISTETBy8gWV6m73AYbHZKW 21 | f0/dwT5soRVfpW5A8LgDTD0CgYEA8Beg00q9jszLzHG470Ys54PR23GVouGgJD97 22 | oQ/huxHueMbzc0NitLy8AeZcaieNzEgSSd5uYYNr0nRPw6Sdjt+M9174avaO6RU3 23 | xbpnbFeIDLjJapsyvS/KbUBqTvXlb5w2kTmTFZi1gU033crWA2emhZHmbJQ+VB0Z 24 | QyodAh0CgYBIgdjqRMbHzxJMk6vo2NnYaAOe2iJUxfgpaAbxuvQtAy29RMQNdtk0 25 | vaNlxDr0NqFjHGA5c0VR5P0zu4ov8mPE6UL+2f797Gfgq9XGuinx7kUaP/U0yLbw 26 | zMzpXyfJQhNuy2nPfpdxvtSvlpu252B6+uPle6VS0cqaT/uqgtFsvA== 27 | -----END RSA PRIVATE KEY----- -------------------------------------------------------------------------------- /jose/testdata/rsa2048.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpQIBAAKCAQEAvTOxOd441LR422jssyUPwa1xRheogtIRYPTu/QeBsiC4FP7I 3 | LwGjOkBPeXIH6gEFmQUvN8QcC15QueA/CWrRHmGwRknqVwvVn1ZfDIsTieQSd0g8 4 | wD7NCYec7OiqArLukipScWpIZe0anfzh8UXdjT+qN4VyIueZ/5afQ+d5pOhjWsOP 5 | YRv2wV/lQOJVpItPU3OlLJc5Lm4ZsamU975YTy4Rve7dWDZUZsQ9q7aXkw9iugLB 6 | LLGqWkqybMnnny6+NDsqlETFI11vp/SJF91ExvDctqGvGFspXWaYzoYPmieZuAEJ 7 | mnDmG04mPUzNUVk52ehMeYyX9j8hR0yO/SMb9QIDAQABAoIBAQCC1562UDGpF22E 8 | /pjCgtzUqaduO6ozXibakEg9/9T3ZJ0pF9FEgLNq81KCwBMtBqviWK2AuURTsFPP 9 | V38AejhH9HK9CRzgObTvzgFJYVyPvYPvrasln8iX0Ir7YyM/XpKRzmbZPBD5O/Fu 10 | VJXEDvbaWa7TWpvF+7iKApX9lbSQD10/bG5d9cmuQeomckEWGeJ9fC0DaqOLZt9y 11 | ylqryRhLTLyXBa7MbxupsduDBshGZTY1AGxj4YD6QS/a6UUCWRLEBz8iuhaYGcfK 12 | jngSMNFjT7DTsgTlg8Fhuez5VYVIB9L4YCyO4LAKWaPAbvfdH4r6Gpi1KuZPT5Pz 13 | avZcujBBAoGBANeKD55KmXGrblhZkf3OcqEmPgnndq1eg7g5rljmFcwdM7Bruurt 14 | ei/FNzkf45w/8cFR8R4JQntn2kAcf6A8lCDkYObABtv7sa0PFOkCgjr0H+/JWKjg 15 | gaKjkagpFugF6FgVda6xrwGojGPgJkEx5oWbljce5R/Vkcu7+3axlt89AoGBAOC3 16 | 9uN79JwWBmExk+D9j/vqFyt0h/PyeHUjeFcLl992dzB8XI96R7GUFm1MOIAAJ2Yh 17 | WLLOONn+0dwEwKBFjDop6tqE5YE18rpnrIOwwzuBuHeCjAXqcHt0WSTo+c9OrJ3O 18 | OSF1VFofZgcJne6HrU/iJruCyHtbfVZuWKR7CXsZAoGBAKwBVW1xAvsfX7PJ5yOw 19 | uPG5XxDwUlkQb/V4spXnJ8X4F+PWVRhd44Bz1hoURMPQk9E+3zilExUAT7+R/peV 20 | QHDvUBVVcSPkvGnq+zjn852wbDwjZkl+wHVWK0sTX2BSNpT0qzF6QrsEEuUxX9Xv 21 | SJOfEkVytk6tVOhNX+Pc3RXRAoGASKMuatnmd42nAkPESTWtFQDV/HXufCwkQ7jz 22 | bS+SJ+ljHYkVYktkYUI8/Zdlq/pgweKFiUafmdeEfloK6cORUDu8bmYGyX1muFpK 23 | qUa51MJZnkfUexUMxtsU9ZlZJmmH4nqGfQov+fGsSRoSsseofencG0BrDXTFTurc 24 | PE6JAgECgYEAy48pOfdVzO1sGmpc9ihLM6nRbuYU0zzE9fd6gF/ACZcYawtBUArg 25 | /7CSuVsbkJnLP+voiC+B8On3ZkpYA8E6nBOcbEft8JF9aeRzC5rqNxxphgdK7QCi 26 | fqS0MskeuMNysBPwlWlWJnBe4QSOSixrkQD3Ymm0i75aUWeTKQy4Lp8= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.rsa2048.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpgIBAAKCAQEA4uI83MBkkLHDoHmLNrd7ooIbzm+ZeX6jSB2HiwpmA7PRjpgt 3 | xBD2fjt8QZ1qXUi9GkSlajiomK5Q64+Dg+6CJp97Lkm4EybwQvHJqbzA+pHFCrNL 4 | DVBea2O/kRBMzdSr7aI0p8gwruVStwADtNYK4nrd45X08SE3Hl5iB4tMBMrOvBug 5 | v5fTaII5ZMQ6AzqqWwk/pTP/dfjKfGPO+rN7g3PQ4/B+yXjDWfAld9dFk7Wl53Po 6 | rC7oqcU4MZMyGImXgi58V7lx+XhRqvcRUx1y2CBUJu6aHgvBERsf+vXSf5q1HiIM 7 | UFYMhn+duLoTRBZj3JPDE36J6SOIHDg8xoQDnwIDAQABAoIBAQCHt7OWjZPapiuS 8 | fAJVuc5AOLovc7yH28QKqHdjKdY6Ur+BH/EIfukkO6spiOOOZ6uO4g9dCgV4R5Xq 9 | Qw/1xJ+gQPgriTeOZVWFhiMO4PVDLh2DOBsmHLROYv295dU7rwMlhEkhMHRGurEO 10 | /Pg6nWsnbT38HMDH2QmipezX/HB90D73R721ms2wffVs1DU4etTEJc/zUaWzuD2b 11 | i2UY8hne/Jv0hIvS7mb2vM/vGJOG7k4mFdKvvGOgsLBR/bwIoMIuSKcDQbf1rTDm 12 | V3NLNwA/irWR8F9SZL7QwY/8z+3vgylTYq6PlPAXrK7Fts2N3Qdp/UYrUxjI4kUe 13 | H3drLm/xAoGBAPmD9oZauAQle5MyvBfi1XU5eVZr0kRpFLoQaAeHI60Aia42+qCt 14 | RQbtk+x+XR3CjA+FoVEr+644MZWTYaKawA2Mt931OVxuQG8CkzRutBmnFK3atsNq 15 | 3yfrOXm+vyQoM5eXmFtLTJwiG8a7EjlgX3Fl4aLMRlkmdwjJy6Y0Tyr5AoGBAOjH 16 | tHBrY1FQSM5qcPeoH5ah4bGKgF6sSOZm5YOF4J42zz0BE/t1vChEZb00D9+2+lC/ 17 | vSeplLhyvKueV+sRObo8VfQAbSOOC3u/Cm9zIbkdilOW8Ux3KXtkvOLxdsTpwvZh 18 | Zqu8LwWe7WnOBXILFmBaLkuOTfe6AGBrPcbbaPFXAoGBAPebqS0zIaGbwMIWeuoJ 19 | RGMMIglM/mC9FsB+P34Y8aJhAkBMdvK0f+ecJEtwKt+5jFxq8+cliqEdSrdwhldi 20 | 0muf1WcCT2YWUwLWv1Ys9bTvRWoxvWS3zbRDjcnvLKeo7WnmGl+enevjPUU9p5wg 21 | sxZJUFzJ8pXNwhqKhvnstxOhAoGBAOczEuBliKuGlgmOZs1TyqwN9OAltAJUE8Pj 22 | hynumn4J6iOpInOrKErGRFZ7kxib4Fq7VeBC6leYfhPmnWP4I+H5c1V55uxddMJf 23 | qLmxHFmEIZOMY/WSlTzdfU3ajiBeHSog65y+t+VZSGzCF16B7KOebkTU/lOCBkW9 24 | vgn4em7ZAoGBAJoBN2+76jXFkd98UFesXWGi9CFUFAffgAeu71RzZsxsbuwEn0z6 25 | /4uxDDxUFLcguK1PBCljeHUFAZUS/+k8eEjsfITWzmixAPQlvYGpYDuU9Z2P4agn 26 | TM16XFyRvNMNqtuY2LovA9FuPdYceoneQj2C1AybyiskRZjUfNCGdWPD 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /jose/testdata/bad-rsa.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDyT7hlA7uO6AjQ 3 | rbdgnHILDYwPa5xYIvhEji+bHCUWw1/L+MuqpajWKGv7toQIioehkYuzeFgnk+QP 4 | zeQVrzvdcY4EJCEGE34xXcgTlX8ZVPqjtzgq0t++f3B4eftRmo5/kDwGpnlvQfUP 5 | NaxbOJjgwkhhZEEi9Lk/pISaszem99AlFYry57uZyrxETJ67NxAsKiEi4fgRr2WN 6 | e1EhSWlEoVVn68br8DhqC/iDW99zVlGD3Xl99GmDluNF0lf24NIAlqrn4mpguJvB 7 | eQQucPwkKdNFTDeFHvFS+2qOvVj29kWIoeKdK6W5izZLz1JTS+K5HaSMV+UYDUri 8 | sQU4P7uzAgMBAAECggEAe7wN0zd2vWDrr3Ql4iXBbrd6QB2ZdsBUut1InhJfNiKK 9 | dqQTjI6PityVV7I59gqXe//QsNLRYVR570AaKqCTF193P9IbMvkdRaQ4GRgMESl9 10 | 28Ah5GxOaP62ti7EEUW1YpqKrHKyLAgoVZ3455QdLRjI0ULaqDkDp+Yg+MZvssh2 11 | hcvAndhE5mGrduudJBoWxSmeuTVLidqkS+Sc8aqyWJORzRYRsGpapq7Ij6hgovvv 12 | OSRF9jgtq+txl8enf3dXO7aXv2VyKgv+9TszZx7s0tyDGaMT1DWMPWY12RUUdweX 13 | Glyy3bcdzjfdN40EpkdjPAgl7RDqupgn9heXuDfIgQKBgQD/SZujqmDpgtU5N1gk 14 | +bKY+1IbuvL+BTynQEJywoPEyln6dBmBQ+KUyQQmAG82J9QMIKGV7z5i4NrloEpw 15 | U3PnAWOPG/xQfzX0qAz3s1Le3yQQCgRBsJrc0M0L7uuYqfjfh/PgN74FZIZQiunr 16 | EqHKsbmHAR/nfsc7lNW0SDgK0wKBgQDy/NdokFlkVDJvJFbNcbkiPZXC9KOnTWBS 17 | dEIt7GYNteJ8QOoh/ZMxNt/WEp8vMpj5LK5hBY2u2UB4MssWuHClRVEZVVop22eg 18 | dySog5srcC+2jCacv7bDO37s2ah+MUR2OFbjB6US7XJaBBKcVKElyYa0/ud1Kj3D 19 | bxb77+0/oQKBgQDxqGYymdg/c+AP13oTFmOgOVfSdDgNijuOP2AnbkZ6BOsEEN8L 20 | 5I0aNuc8afDcnPs3t7P+UIkH5L6R3BhbGESBCmmKUP2Z3bHftS0BVbk+zJBAtpqs 21 | 7FbMbMONZk+TJmM2hmWvfFTemfgjSjyAkBSj4XU0fTYMV5CVsCBUFoEmjQKBgB/X 22 | WjLtl4k6L1G5JVbOrD/8af+eJ0PpM9IaQgHalJT/XKqDpyrFG+C7HCHlVs7MhpdA 23 | b6lvHN3owjX+EfbsPHar2rDDKomJos64Til29YJ/tQDq5LRtuvlidoN7EkVXF22W 24 | fGxLuCn+y5lYJ0gtHuDgw7I8JQCJhIZzrENfcWuBAoGBAJC235n75zdlnbWJ9i6U 25 | a3Q8maXdsMABDfrVF9a9DPgY9djiG5SAulNnTri4+CtblXAPZ1Wc3fX/hsHrfsAp 26 | RsnJpzBDHGrV5LJ33wlNkqHESuEDLZCJBRvrFVPkz/u7wnJ0PIJbIEpD3+6BElko 27 | trP9GV/B84/OupCdc2VosOn+ 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /jose/testdata/rsa.enc.priv.json: -------------------------------------------------------------------------------- 1 | { 2 | "protected": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6ImVoWDFmNldfXzRieF9GZlNHTFNpLXcifQ", 3 | "encrypted_key": "vKLfYBmT9hmhExKrNcDrOBlgmUZFvCxt", 4 | "iv": "wlzL3r2Kd-FAbVat", 5 | "ciphertext": "75c0DAGsgbqfnQctGw4aczBYvWAJ4yOixKpeJnbZehn7wbyuEmVa5glgmO-cqNjv-6Ev2959etaD_hjVvFTMKPi7K6GvZt42b_4YNZjqjL15UkbV_fvIf3BUODV7RxlTNwY4DbWzUZeNk-RUMpxnH9K3sHYeEBwAI9jAdu6On8LImP5-VbVlqNHCySIKtA35rr7AhtXxdZph5oYY_P9CY4LYVzedi_KmwW5mHr3CJUXaanQWc8oGnpqR0K0eLFLR7vLxcSYnt7VozcIVOopRMvhdHrLMD2HB3QrNKSp1l062BMu8HnDJ8FJNEoWLaOMv70QtaNGLBZ_RyjAxXmdU3o8AZNP9Q1dcvwF0RztjPuBtaMgK2L3iZ9YQAAipGQp-epD_Cn1Oxe9BWepJxE-EK1SkugZYp0rx-ZQaxf5jykV08Bnl--KZfE4cf-SWB0kt6EPg00NXMTr-a1rQE-yW6cnhnKOYkOL1Z6rjRvqu0x1Tg9ca3zzgeeiReRpDiNGKpi57J023bosIydmMDxeErjNlSlMCmHD2r4_-Y2jsSOtniDlPv33eJfBT4RdzGfhKQqCkWem8Omy5NpvdteJOLKLq3JOcM7sUJFXKKWJu0kTJzYowS80aFXpTUUbncPAolXHqJbhbK1DyV0wAasaDQvCbF7q12bQap9s1Vy2y6cHBFDQvjiiDokMnzDOymgYmvtXY5nXv_udrIMXLOgIQm8napHPrkHVtOz49iMTAb59xXdxlf02z8l4jCEhcsAvE57WlanD-S7nHiOzFHq5PcPG2BiplSYRxViv8yP8XGhK-npFQhyEvVuwSNweZaHGz_brtPMFv7gpcJhS8tJes0yQFmfH_tmy-rvyROjOTjZjKNZlfJbRyCvsJtaGx2Y5QNl686nBKbB5mH3so1gvXmITGU3FWVeAoP2xVLv-hfQii5pfs38B5NfYQ5I0AbklSc-ZrsIi-1Ghffkwy6Kk_zSmNtxvZXjUm7e6_sKgso6jlvucAxAEtKT5pLf26fZmrHFI0IFNnMlH4hGZfY2EALYkJfWP8CfREAWVB5F4zQZoPyZ3KCk0TvS_BgqwcFL4aJAPtnz0zlCLPfPY6B2FyMvktnWFL09oeGWt4tTEzCbWnaziKAMboq9WbUIjfR5TlOrKlJaqOKbgbjsMSE0YoHj1-QS3DI5hShEcTMmk13nA38T8juvMEYWuP-X3BhXYiI6lPxVgpACw5E87zoY72xL__rsQ4l2ykB3H2Rn88hBm3rOoSz_IfiYxgunten-CX02w-UN7yDZI4No12yy-A7BgY1tikhdVWvhLhAERBsbSptd_fIZGDdu5YiCFCd21Es6T6YDUJV5QPpH4PcdU_se5zdRiVPitUB0NhsgwdgyBtyzty8uWsdzYeR9f4-8TyDQJDpfswg3x-f0O2cIjto3B4p0p1TWrY5g-R-i_waHbPqiCSsEIIpK2Xa_5sz0rD3pTDD1AAmSHEoPv2CR3s-0YmO1ic5aYZGb3epWDX0y5ZERc7uB9FolAz_rijuR2W4ZMZhQ", 6 | "tag": "iMXAGrj6xHaxuVL49vn-pQ" 7 | } -------------------------------------------------------------------------------- /x509util/testdata/google.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIExjCCA66gAwIBAgIRAP1vPiSYwlsdCAAAAABH8DMwDQYJKoZIhvcNAQELBQAw 3 | QjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczET 4 | MBEGA1UEAxMKR1RTIENBIDFPMTAeFw0yMDA2MTcxNDMxMjJaFw0yMDA5MDkxNDMx 5 | MjJaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH 6 | Ew1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgTExDMRcwFQYDVQQDEw53 7 | d3cuZ29vZ2xlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOFYzxk3Ghpj 8 | cPvTNffIAqyY4p62NFaISj/X66RMGO7rs0RyM2I4ch1hiEP/alWb/+81BzA+R1nK 9 | w0ZKwy86Kh6jggJaMIICVjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYB 10 | BQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUjqNsRxKnCgdblFHWKj9y+TUG 11 | RSwwHwYDVR0jBBgwFoAUmNH4bhDrz5vsYJ8YkBug630J/SswaAYIKwYBBQUHAQEE 12 | XDBaMCsGCCsGAQUFBzABhh9odHRwOi8vb2NzcC5wa2kuZ29vZy9ndHMxbzFjb3Jl 13 | MCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2cvZ3NyMi9HVFMxTzEuY3J0MBkG 14 | A1UdEQQSMBCCDnd3dy5nb29nbGUuY29tMCEGA1UdIAQaMBgwCAYGZ4EMAQICMAwG 15 | CisGAQQB1nkCBQMwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5wa2kuZ29v 16 | Zy9HVFMxTzFjb3JlLmNybDCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1ALIeBcyL 17 | os2KIE6HZvkruYolIGdr2vpw57JJUy3vi5BeAAABcsLn/z4AAAQDAEYwRAIgTB4w 18 | h0IyoPg5FFwxva6DkCumsXIIhKmHO1xk6HrOpDECIA0c5Y7Yq2mgGu03QPdbPRLb 19 | dBF5ISGltoW1ni2LkLIsAHUAXqdz+d9WwOe1Nkh90EngMnqRmgyEoRIShBh1loFx 20 | RVgAAAFywuf/bgAABAMARjBEAiBUcGdSwAP/13zLGH4xcJ5l7rYoif6lb7Ymv/4u 21 | intIHQIga1qNo582mt6FkPUYcKNq77MR9MPQYjJj+SQg266bbacwDQYJKoZIhvcN 22 | AQELBQADggEBAFKf5klhZEz9FwJlsu6/vnAn9lUKM2hKVKxO4B8T4f6PuY6dlZ3T 23 | g6mvdtsiLjAZ8v6WL6Bn0v15kTh9RhrKwEwVbLLfoXZbQBygV9B/k+HOCgMEb8U3 24 | Nn7chIP1kTJcyy3BW7TSU0WODmNuEusX0MQcs5TNl/omwdKkzpB6NjXWhnwgzCeD 25 | 1nT33vvq1pwgg28ncIBJkqUpDca7hBDQjx1HYEq00euF5/zDWLV98mH8ORPSC2i2 26 | N7e0OMNT3q2HJRtHor5USuzehR86u3Aie90Z6jBvG/kNsGSgjUAdj/PAlVBj9GcF 27 | KtLwFt/ee1wps0/VGR+gqkoJps0BW8Tv+1k= 28 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.rsa2048.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDNbU3EJBRhM/mr 3 | t5e6Ys8Vs+s0QpNy4tj4aPycySvtdvp6DBmwIpzDwyiv9Yey4il7yFdXddluIZAL 4 | Q43s9SSnss2P43T7nGd1lJivdBRiyNzAKjdlpLat80urpLcccEp+WGbNjyP2DWJ4 5 | ZglWZ4drbBni/an6tpMC8TkHibhfXamazRwDquBnOa6W4Gkd7sP8jwfwa/fXMjfb 6 | buaLm4PDXC6lkLQTNQdZEN3nEFgvQcOsOuOUbMOqaGP1epV/sVsNSgWqlS3oL6Pm 7 | oNiNe+nBiSACrYoplBD8Wx1dG6k+bI+WEUF9IcbCozpYktoxNXEwg4ysVhTZ4+Wp 8 | Thh2bzWfAgMBAAECggEBAMYbnR2Eteqv1x2U5kwnMhJ5+l/hvJTU0+1sQgFpuGU/ 9 | knrU5IkKOChKMxjOLlmC5gKryB9eVZtx3poeQea82uam9rrG3nAv+05XSZAa3/YM 10 | Q2dGzznEyS+kK9uR880HNa/2zN18J3AIpGf77xFWsjAUhjpz6tMP82KpAxiT5iyA 11 | SIJ00iibr9o48iNxciow9wa0H+LcuBIBiznzC9J1YgZLcWL4eKjcg8PKcoOGHOE7 12 | FrsFlx41c5/HL1Io7mxA8kw+shN+TyrfgMcLAKr2NTmGgTed0E0CgdwvArhv4S4T 13 | Hb9+Ss2pm/pTjgHXn1/tyQV0DWGg13/ACfl150CCJAECgYEA/iuDIyUFNCT2x3UF 14 | vK5Gt50WgHM5jQC3OJJ5iVe3t2yGrZf2AN7rLmpJZ9N2xMpfU4qNJGv8bjIJqsim 15 | GIUpLv+XkTjq+I73L9FUgJ832FRo9KOyx7rxe7wpK8q0qQ5reGfYIgUGWanxndw+ 16 | cchXdE/GiGtWBd/RkEvTKrOWVwECgYEAzufytrP2rEqml6jmUw0UKuYc79WLSivu 17 | dLYPzoN2D1ogCvR3qiZoHDfuLs3SyJBMRyHEOfhXPudmMCIL68mcy4ZwSNXjlc1t 18 | QdrPUEy6bE3yKzuZJpkKZNgsstkW3folxcucAK1rD39meRpXZnmuHXaWIvEbb3MJ 19 | qp9JAegbLJ8CgYEA0KGg5CFIMzRASRr6mZUoQSG1zbxHOkGjI9G/54fUKsDvj+DT 20 | soVI4PGnzYzbyc8gDnAFSSdGrqFuI/zNsgTj+Ese+7qPzXV025BlX6rR6UXoXR9d 21 | 6eq+u8WIugSK5NYMS2paFBqxyrnftaeKrlU3zCaLnYEVvH6rA1nqPPvq5QECgYAv 22 | +z4f/G/x2IX1maeADwJkSGThgWYB11o/GpFj1LymJsJTiAnQHYP7N0U2+WguNrhZ 23 | rozw3JRu8/6QnvSgw2pnEFAts9xJOxBhOzrkZka9Iv5L5FBJ0SfF5xPGje1toLrt 24 | uZ/90DmJqIO9BczK6ODl2EBM7hjsqYLOXI3zsT3MBQKBgQDmL28YaQk7dqTDi7y/ 25 | gFqdfeFxNJe+wtxunewLCEi/TwCS5h5YDZ2GOWSClVdW6jJXsJ+nZZwo6g6gND9s 26 | d5rBpz7vyvtyZimDDMmc8ARn/YG0ubuWfHtmYy4UVyacRN5kb28MIzjDwws6Ms9F 27 | hFgS1x4SifkCh/YSDvuXhBLrYQ== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /jose/testdata/host-key-cert.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg492YHGHNhvf6aTEfaGk1zG2eTwTiOc3cXytpcBkVFQIAAAADAQABAAABgQDDA6iolHi1F7d/tZcoSm5RPjznn+Td44+VtUYWWBL0SQ1rVuyzNXq1T7hHDRxxNf92mCHHeHhRZYPKmh63GZiJSWkVmqn8By4qyQB5EpuE8H+5czBNtNpk1GG+q7u5eOBSIh9F4Zgzb/h7+BwGHU4srRhUuOG/u4DmGsEONVkpnD1aljgIz9vWRauM6/bJ20M/TiNL42L6YEclDoNoV9m1kkFM6Oib+6XFgo9Ihd5E41Y7uAPFe5kmTaHHw+dmjQGTVYqF1rOiope7dyh1EIkzDWIoOHOlpnKYTaPICkoKuVXj/NfHE0vsv0ltl/hamy0D4GQx8n0X/Wi48yNnYZke6Xc6jpXIt3YI2M8vUtYI5mR5wm7nQCIMH1INbXxKakrAIqtaEq5+OIstNO1agX5FwMwjfQha/fpUnhbw+Btxc/QuNnvI/wM+EVbm44YZuHEUoN9H+9LigAuiRzpqtLbPrBhssxNTcvpcbiOaYFkpj/JNbvn7ZCmQb/sF/GkXyrUAAAAASZYC0gAAAAIAAAAJbG9jYWxob3N0AAAADQAAAAlsb2NhbGhvc3QAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEAsDam+5VgtC930iv802TAQBJQS4UmbrWl0fAKLn8QPLZsvyVOYtt/bBL+5GA5kfx8RDAaTjmlS/Ma8UatYURUyYo+h8PsIg1vZffuY6ArUtYeGbkW7K/4dX2Xe0glwzTYFRbDIKr6cpo4YAetiAbmmfq/h5iVK9UWfCKZzRWsfw+ygPfH97LBrjIDwgzqylnTWVmlFfci9NSV1HW4mqbrZlBcX4NjYAHyqXkGMDY7D2BgnEe59xnfUemyxAUYYq76zAs0TBTRUhGiOdlvGWAAq+hClzEWP7+251+QIwKOw6lzq/e7qFqLJzIW1lSoXE/VGhKkAKzQD5o498oqktPoI6lahz2hfqjb9rbo3+4whG5gc/KDvPSpNf1OnLAP+J0zIPESpWiVO8ppHtBQ33BobPlo4vTajpSIIrVgmSf1T1Y+JFfhBD3eCbpmJOFjarWkfN6Vk0RKfNxrAezPq1kn8V82MjhBTx6hXbSLyqntsMlTtycyYrVVITH4mGxUEtfTAAABlAAAAAxyc2Etc2hhMi01MTIAAAGAlsGPh0gScTejMNWBsEajHLdb3SrfI848lITbptqDMfjG2xEWQyp20xmt0u6+nx/UKsDtHZ9T4OM5htKvZjSLxSEE3ABQ7MgjxivTd65aRRP3cqTuwmfOTzLacHOX4nSATJ5/vRNFIRne6O8eZYMvIyRlAFWExJe1gtiQVXbTKD2WlQjSo+/JUYj/t6G9ccCT4shxWqkm019uvyNnujN6HT7f8d/AHos5jm23xHYRkhYeQLJ9yX5wR2/GEQaTGet99N27H55UXQTYsmd4JqgTuG+UAL9nxYfMp4rMEJajAhZ9Kdye2Eo+2/0WfbOYE3YxYWMOflymZevLXHjT69zMwhUtMZ8QSem9qNxJ6JEmQVA7aGEyvHNw1OV9Jd8LOtZmJDuFdAqmqN5yZKcyxssLd0Pe1H8W1XYjCLvOFov8w8F6/mL3DTsUAIfn2CpIbu3lV+1JOAJMRcsz9drDJY7++8f2qrG9uipS01n9MjjKZfY29xFVOOmB8M3uMh7kCbgl mariano@overlook.attlocal.net 2 | -------------------------------------------------------------------------------- /nssdb/sign_test.go: -------------------------------------------------------------------------------- 1 | package nssdb 2 | 3 | import ( 4 | "encoding/hex" 5 | "strconv" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestKeySignatureID(t *testing.T) { 13 | tests := map[uint32]string{ 14 | 5: "sig_key_00000005_00000011", 15 | 676985114: "sig_key_2859f91a_00000011", 16 | } 17 | for objectID, metaDataID := range tests { 18 | t.Run(strconv.Itoa(int(objectID)), func(t *testing.T) { 19 | got := keySignatureID(objectID) 20 | assert.Equal(t, metaDataID, got) 21 | }) 22 | } 23 | } 24 | 25 | func TestSign(t *testing.T) { 26 | globalSalt, err := hex.DecodeString("629bd383b3f9c0cfd0842f994acca3a9c638bfcb") 27 | require.NoError(t, err) 28 | passKey := intermediateKey(nil, globalSalt) 29 | 30 | salt, err := hex.DecodeString("03070DAD39B0D0006FEC59632040D2D56DF1625BC2E92D30B233DD239CCC1901") 31 | require.NoError(t, err) 32 | // just the 32 bytes of private key material is what gets signed 33 | val, err := hex.DecodeString("d692a48a8e5eeb6ca34eaa53144506228eee4da5fdf3402c80794e409690e78b") 34 | require.NoError(t, err) 35 | 36 | want, err := hex.DecodeString("308180305c06092a864886f70d01050e304f304106092a864886f70d01050c3034042003070dad39b0d0006fec59632040d2d56df1625bc2e92d30b233dd239ccc1901020101020120300a06082a864886f70d0209300a06082a864886f70d02090420f9e1dccbf806dd00c6c450c11da24fb21ef220dc1d153764473d1e10ee93bd2c") 37 | require.NoError(t, err) 38 | 39 | pbkdf2, err := newPBKDF2(true) 40 | require.NoError(t, err) 41 | pbkdf2.Salt = salt 42 | 43 | sig, err := pbkdf2.signature(val, passKey) 44 | require.NoError(t, err) 45 | 46 | pbmac1 := &pbmac1Params{ 47 | kdf: pbkdf2, 48 | mac: hmacSHA256OID, 49 | } 50 | got, err := encodeSignature(sig, pbmac1) 51 | require.NoError(t, err) 52 | 53 | assert.Equal(t, want, got) 54 | } 55 | -------------------------------------------------------------------------------- /kms/pkcs11/pkcs11_no_cgo.go: -------------------------------------------------------------------------------- 1 | //go:build !cgo || nopkcs11 2 | 3 | package pkcs11 4 | 5 | import ( 6 | "context" 7 | "crypto" 8 | "os" 9 | "path/filepath" 10 | 11 | "github.com/pkg/errors" 12 | "go.step.sm/crypto/kms/apiv1" 13 | ) 14 | 15 | var errUnsupported error 16 | 17 | func init() { 18 | name := filepath.Base(os.Args[0]) 19 | errUnsupported = errors.Errorf("unsupported kms type 'pkcs11': %s is compiled without cgo or PKCS#11 support", name) 20 | 21 | apiv1.Register(apiv1.PKCS11, func(ctx context.Context, opts apiv1.Options) (apiv1.KeyManager, error) { 22 | return nil, errUnsupported 23 | }) 24 | } 25 | 26 | // PKCS11 is the implementation of a KMS using the PKCS #11 standard. 27 | type PKCS11 struct{} 28 | 29 | // New implements the kms.KeyManager interface and without CGO will always 30 | // return an error. 31 | func New(ctx context.Context, opts apiv1.Options) (*PKCS11, error) { 32 | return nil, errUnsupported 33 | } 34 | 35 | // GetPublicKey implements the kms.KeyManager interface and without CGO will always 36 | // return an error. 37 | func (*PKCS11) GetPublicKey(req *apiv1.GetPublicKeyRequest) (crypto.PublicKey, error) { 38 | return nil, errUnsupported 39 | } 40 | 41 | // CreateKey implements the kms.KeyManager interface and without CGO will always 42 | // return an error. 43 | func (*PKCS11) CreateKey(req *apiv1.CreateKeyRequest) (*apiv1.CreateKeyResponse, error) { 44 | return nil, errUnsupported 45 | } 46 | 47 | // CreateSigner implements the kms.KeyManager interface and without CGO will always 48 | // return an error. 49 | func (*PKCS11) CreateSigner(req *apiv1.CreateSignerRequest) (crypto.Signer, error) { 50 | return nil, errUnsupported 51 | } 52 | 53 | // Close implements the kms.KeyManager interface and without CGO will always 54 | // return an error. 55 | func (*PKCS11) Close() error { 56 | return errUnsupported 57 | } 58 | -------------------------------------------------------------------------------- /kms/softkms/testdata/rsa.priv.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: AES-256-CBC,dff7bfd0e0163a4cd7ade8f68b966699 4 | 5 | jtmOhr2zo244Oq2fVsShZAUoQZ1gi6Iwc4i0sReU66XP9CFkdvJasAfkjQGrbCEy 6 | m2+r7W6aH+L3j/4sXcJe8h4UVnnC4DHCozmtqqFCq7cFS4TiVpco26wEVH5WLm7Y 7 | 3Ew/pL0k24E+Ycf+yV5c1tQXRlmsKubjwzrZtGZP2yn3Dxsu97mzOXAfx7r+DIKI 8 | 5a4S3m1/yXw76tt6Iho9h4huA25UUDHKUQvOGd5gmOKqJRV9djoyu85ODbmz5nt0 9 | pB2EzdHOrefgd0rcQQPI1uFBWqASJxTn+uS7ZBP4rlCcs932lI1mPerMh1ujo51F 10 | 3aibrwhKE6kaJyOOnUbvyBnaiTb5i4WwTqx/jfsOsggXQb3UlxgDph48VXw8O2jF 11 | CQmle+TR8yr1A14/Dno5Dd4cqPv6AmWWU2zolvLxKQixFcvjsyQYCDajWWRPkOgj 12 | RTKXDqL1mpjrlDqcSXzemCWk6FzqdUQhimhFgARDRfRwwDeWQN5ua4a3gnem/cpA 13 | ZS8J45H0ZC/CxGPfp+qx75n5a875+n4VMmCZerXPzEIj1CzS7D6BVAXTHJaNIB6S 14 | 0WNfQnftp09O2l6iXBE+MHt5bVxqt46+vgcceSu7Gsb3ZfD79vnQ7tR+wb+xmHKk 15 | 8rVcMrB+kDRXVguH/a3zUGYAEnb6hPkIJywJVD4G65oM+D9D67Mdka8wIMK48doV 16 | my8a0MfT/9AidR6XJVxIkHlPsPzlxirm/NKF7oSlzurcvYcPAYnHYLW2uB8dyidq 17 | 1zB+3rxbSYCVqrhqzN4prydGvkIE3/+AJyIGn7uGSTSSyF6BC9APXQaHplRGKwLz 18 | efOIMoEwXJ1DIcKmk9GB65xxrZxMu3Cclcbc4PgY4370G0PfCHuUQNQL2RUWCQn0 19 | aax+qDiFg1LsLRaI75OaLJ+uKs6rRfytQMmFGqK/b6iVbktiYWMtrDJDo4OUTtZ6 20 | LBBySH7sAFgI3IIxct2Fwg8X1J4kfHr9jWTLjMEIE2o8cyqvSQ8rdwA25MxRcn75 21 | DGqSlGE6Sx0XhWCVUiZidVRSYGKmOmH9yw8cjKm17qL23t8Gwns4Xunl7V6YlTCG 22 | BPw5f1jWCQ94TwvUSuHMPYoXlYwRoe+jfDAzp2AQwXqvWX5Qno5PKz9gQ5iYacZ/ 23 | k82fyPbk2XLDkPnaNJKnyiIc252O0WffUlX6Rlv3aF8ZgVvWfZbuHEK6g1W+IKSA 24 | pXAQ+iZBl+fjs/wT0yZSNTB0P1InD9Ve536L94gxXoeMr6F0Eouk3J2R9qdFp0Av 25 | 31xylRKSmzUf87/sRxjy3FzSTjIal77y1euJoAEU/nShmNrAZ6B8wnlvHfVwbgmt 26 | xWqxYIi/j/C8Led9uhEhX2WjPsO7ckGA41Tw6hZk/5hr4jmPoZQKHf9OauJFujMh 27 | ybPRQ6SGZJaYQAgpEGHSHFm8lwf5/DcezdSMdzqAKBWJBv6MediMuS60wcJ0Tebk 28 | rdLkNE4bsxfc889BkXBrSqfd+Auu5RcF/kF44gLL7oj4ojQyV44vLZbC4+liGThT 29 | bhayYGV64hsY+zL03u5wVfF1Y+33/uc8o/0JjbfuW5AIdikVES/jnKKFXSTMNL69 30 | -----END RSA PRIVATE KEY----- 31 | -------------------------------------------------------------------------------- /pemutil/testdata/openssl.rsa2048.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: AES-192-CBC,A8BBBFD06EA695AC6FF58050ED852856 4 | 5 | u4CKYZAVdUWyIJMlJ4HA0k8B6Ix1qQ/PB8aShhIZ0zjkfrfO9eBVoo5Is76Thid6 6 | dWp86pEAbYZ6vxOBXF9Gnz0KQ8GJHjmHAj/zPKdV7hTcv/e+isTCiw9JsVHy9ejN 7 | EGUDTMjSvQMKyQsbLt7g0ENwBKu1JCKEN9n6TnSzyph0NOQ5I15CgF9A3UTD6ngP 8 | ZIBTjFsPI2MoDCP4LMurICkauuoSMADh4u6gTQ8oWc5OnM+8ujOtq8kg91WM8CuO 9 | MQ1lxFzNFRWQKtM9uIRXtKifaPP7RfZmTkfTIxDaxo2YFbb3+fH2NO84xLjU/DsC 10 | iSvPpMqfqhFM7/mXNEVkoeriVqsMshxmE0z0o3Yzb7fQIm+d2HKxQ9bGDR67Q+rz 11 | WoR2QedIUiI0WEfHnJL9b6m8DVU9SzejeM6DHRTlpCO76i+gVZRwG1CeEE7P00Gx 12 | 0nKID217RwWubWOlSZA8CGO9w7DeYYL+DxSvtc8oG5E3PHhD8rpNFxhU4UnUyrjz 13 | bPSI3mfVALPPppZVqOxhTxKtXo5A+IrUbz4Wrya/7HO/07gZ7E7msXaz48cLn1yq 14 | c5LvBmpAAib9Z/Wdh1QIYFyx1iBQ8Rq7S2YhkjcT1wjdweoGF/YmQtIaSBNwCFH5 15 | oaOf7lGOQ+Thcke6k0lWfITeYml67Pz70oJXZH4K+ZLA+ZULe+N4lTt4kcYxRinN 16 | wOXaPpo1uP53hDWW4hc0cGBUusRuWpyAIvHNk2SprKtrjAyOB5MWQHGuDzzaihEv 17 | H8PwUt6gUhq9e+0jYTj/qU1dibK/5Dlwb4tozABkT65v3vKU2OG+qlQEm6/6kKtS 18 | Xmu91m9unB+SMKa2fabW3nGiM+nvR8gdbm203mhK6/3IgduOts7Npy4L5hzuf4Zy 19 | 15ELEt6ssv1Q47Y616e5WIwAoSz51cNkfRoTxk7PjGWwIhvJtbQMgZF1c1VWP0z8 20 | vWOUQPMTZETXwFrSwC8Tc8+utzTuJ66k7BZUTEeidudCrL3tHbk6Cc4VNPnQN/rl 21 | YkzQfc20cJVYQWcqwfbmEuH+lh+a1XMyRC6VPI3NoXRNvHBALy37TkiFROZEgFlS 22 | bj/jZEaBchOsr29v9Zn4DqpGDaCTxtigAphhyjo16/1CeKE67/DyTeBVvOj85Lx6 23 | wEKUOBNe+ldH37H9eiObYOT8vTKZJQRYcygtWjJ3Xo1qAb+zfBm1qB97wNil7hFB 24 | CmbXk8JNPfEzUdisbTrT3JNmAFSrjPAmG291+z/185xalGcY1P9WoixgV88eMf9H 25 | a6ynWVvHmH5rKiX9yBHhsMND11GjWczEX2EuzQZW6SrjZAV+FPVZdtUDK/iXHcLM 26 | mfHIpyurEoYMQ6sjfXJf3kK2g8g/sW5zZQ/SHBSzwoQYDu8vLYSVhu/Ip+4kaTEL 27 | 3VB3eLZsdRl/X0GLDAdn+pjOkVn5zLPKb6EXvd/JWWSxpz7A92aDc685qANnGvPh 28 | tMMY9qlcaD8gjddPJeLi6oR21SDItc27TdQBF29tA/B1x6+jvBBsaDmLBv6FZwXE 29 | rOJjROMg7yyZlb+v8s7J3tOgki+ZgNEyEEY4ksQUvHDu3/gLp+ofd4JBfji7HPrt 30 | -----END RSA PRIVATE KEY----- 31 | -------------------------------------------------------------------------------- /kms/kms_test.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import ( 4 | "context" 5 | "os" 6 | "path/filepath" 7 | "reflect" 8 | "testing" 9 | 10 | "go.step.sm/crypto/kms/apiv1" 11 | "go.step.sm/crypto/kms/awskms" 12 | "go.step.sm/crypto/kms/cloudkms" 13 | "go.step.sm/crypto/kms/softkms" 14 | ) 15 | 16 | func TestNew(t *testing.T) { 17 | ctx := context.Background() 18 | 19 | failCloudKMS := true 20 | if home, err := os.UserHomeDir(); err == nil { 21 | file := filepath.Join(home, ".config", "gcloud", "application_default_credentials.json") 22 | if _, err := os.Stat(file); err == nil { 23 | failCloudKMS = false 24 | } 25 | } 26 | 27 | type args struct { 28 | ctx context.Context 29 | opts apiv1.Options 30 | } 31 | tests := []struct { 32 | name string 33 | skipOnCI bool 34 | args args 35 | want KeyManager 36 | wantErr bool 37 | }{ 38 | {"default", false, args{ctx, apiv1.Options{}}, &softkms.SoftKMS{}, false}, 39 | {"softkms", false, args{ctx, apiv1.Options{Type: "softkms"}}, &softkms.SoftKMS{}, false}, 40 | {"uri", false, args{ctx, apiv1.Options{URI: "softkms:foo=bar"}}, &softkms.SoftKMS{}, false}, 41 | {"awskms", false, args{ctx, apiv1.Options{Type: "awskms"}}, &awskms.KMS{}, false}, 42 | {"cloudkms", true, args{ctx, apiv1.Options{Type: "cloudkms"}}, &cloudkms.CloudKMS{}, failCloudKMS}, 43 | {"fail validation", false, args{ctx, apiv1.Options{Type: "foobar"}}, nil, true}, 44 | } 45 | for _, tt := range tests { 46 | t.Run(tt.name, func(t *testing.T) { 47 | if tt.skipOnCI && os.Getenv("CI") == "true" { 48 | t.SkipNow() 49 | } 50 | 51 | got, err := New(tt.args.ctx, tt.args.opts) 52 | if (err != nil) != tt.wantErr { 53 | t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr) 54 | return 55 | } 56 | if reflect.TypeOf(got) != reflect.TypeOf(tt.want) { 57 | t.Errorf("New() = %T, want %T", got, tt.want) 58 | } 59 | }) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /x509util/certpool_test.go: -------------------------------------------------------------------------------- 1 | package x509util 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestReadCertPool(t *testing.T) { 9 | type args struct { 10 | path string 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | wantSubjects [][]byte 16 | wantErr bool 17 | }{ 18 | {"ok dir", args{"testdata/capath"}, [][]byte{[]byte("0\x191\x170\x15\x06\x03U\x04\x03\x13\x0ESmallstep CA 1"), []byte("0\x191\x170\x15\x06\x03U\x04\x03\x13\x0ESmallstep CA 2")}, false}, 19 | {"ok dir 2", args{"testdata/capath2"}, [][]byte{[]byte("0\x191\x170\x15\x06\x03U\x04\x03\x13\x0ESmallstep CA 1"), []byte("0\x191\x170\x15\x06\x03U\x04\x03\x13\x0ESmallstep CA 2")}, false}, 20 | {"ok file", args{"testdata/capath/cert.pem"}, [][]byte{[]byte("0\x191\x170\x15\x06\x03U\x04\x03\x13\x0ESmallstep CA 1"), []byte("0\x191\x170\x15\x06\x03U\x04\x03\x13\x0ESmallstep CA 2")}, false}, 21 | {"ok files", args{"testdata/capath2/root1.crt,testdata/capath2/root2.crt"}, [][]byte{[]byte("0\x191\x170\x15\x06\x03U\x04\x03\x13\x0ESmallstep CA 1"), []byte("0\x191\x170\x15\x06\x03U\x04\x03\x13\x0ESmallstep CA 2")}, false}, 22 | {"no certs", args{"testdata/secrets"}, nil, true}, 23 | {"missing", args{"testdata/missing.pem"}, nil, true}, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | got, err := ReadCertPool(tt.args.path) 28 | if (err != nil) != tt.wantErr { 29 | t.Errorf("ReadCertPool() error = %v, wantErr %v", err, tt.wantErr) 30 | return 31 | } 32 | if got != nil { 33 | // nolint:staticcheck // there's no other way to compare two 34 | // certpools, https://github.com/golang/go/issues/46057 might 35 | // fix this. 36 | subjects := got.Subjects() 37 | if !reflect.DeepEqual(subjects, tt.wantSubjects) { 38 | t.Errorf("x509.CertPool.Subjects() got = %v, want %v", subjects, tt.wantSubjects) 39 | } 40 | } 41 | }) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.rsa2048.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn 3 | NhAAAAAwEAAQAAAQEArpuGzB+AZv75D5ZP6mwTKxZWFM1ZVEJ7AWLpzURGW+4rXQUWrvZ7 4 | o0mIU23bcDIB9IBJ16fYI/x3L892HRmDP3Dl2d9+Am5k0NHKolfdHdkH9N8w2Uu3s7+ymp 5 | qtL3ZANDacOZUzpmSp0HDYmwQKnKdgXikgyGBjE2TLBBzh7D1/Y3cKRFOEHrygLM40xf1G 6 | jzS1aXzLBD7lfQ/JdNhj1YPB2VzDWbePN55zdzDJxKiLqkbqxB8+8UvVOUban+OXEHhRHA 7 | 1yWtoIFZi1X6R4puKh0XgN6ks+UIoLwEdCN16wSr+TISx9DTw2sM3gIBdB0dfAgJKfvygD 8 | 9wgOhV1lrQAAA9C8eb3xvHm98QAAAAdzc2gtcnNhAAABAQCum4bMH4Bm/vkPlk/qbBMrFl 9 | YUzVlUQnsBYunNREZb7itdBRau9nujSYhTbdtwMgH0gEnXp9gj/Hcvz3YdGYM/cOXZ334C 10 | bmTQ0cqiV90d2Qf03zDZS7ezv7Kamq0vdkA0Npw5lTOmZKnQcNibBAqcp2BeKSDIYGMTZM 11 | sEHOHsPX9jdwpEU4QevKAszjTF/UaPNLVpfMsEPuV9D8l02GPVg8HZXMNZt483nnN3MMnE 12 | qIuqRurEHz7xS9U5Rtqf45cQeFEcDXJa2ggVmLVfpHim4qHReA3qSz5QigvAR0I3XrBKv5 13 | MhLH0NPDawzeAgF0HR18CAkp+/KAP3CA6FXWWtAAAAAwEAAQAAAQBOph+Bsm7T9eWZ78rv 14 | fN7leZospJKoMYnWhgdqPmay4gUGUVR2WvA2DNkrO0CsuNnImECqsx/Ylc/Z6Uj6spM78E 15 | 6YZOMNlUw0A0uS9KDU4P2Ef0QxnLmSbba1jRaVWl5xJmgYR+yL9qvHCA2JRbjB92KhB0WM 16 | /F2kTrJjl97r2ci5OD1EeGDRgB9KPyYGdUW2KltZ8KZWKtyKKTTdfKDWQGN50gDbMh9GPq 17 | g78M9A74pcZ14p4T8PpyiWrTJh7dmtufI+Tm6HEd+LLNm+s67rf8v+1q00PEoy520sxjRK 18 | t5n/beiwJqJO3z84bOu1EABa4b+4VwH9twIRh2dWXcrBAAAAgQCnTpbxFSd54X1tb7Hj2v 19 | aJDF0ecJfOT+gr6/CoCmXRVSllc99Fp6KR4VTECSuo0VzXUDy1YY16dG3/WrhhV5mrIYVf 20 | SP4GkNLLuOLNgkmHlnQwFgXGBPPJLHP9B+nqRFTVGGx1b4y6MITKbBOSgcJNeD+STuuIur 21 | 1R7tR4mID8KQAAAIEA4aEAUZ4ABQquCvIVfwM2JiLf0vdrHJX/m0VziZAWE2HnD+WXX3kV 22 | RVstlMUs7JvhJP4/+vlEODAtdl6eY2PrXVsJh/Zq9PRyb73k4hoqzQ5KqrBcen1ooeefx4 23 | HpwFk5fcCNB9VQTMfK9V67CYFbCcEEYqDeO9/VmpkcVow1vIsAAACBAMYcXhsN7Qzv+RG9 24 | cNVZFqpiM7WXSibPObdfYftKl1C0QrLVwLf8f17hCaaMDpbvWHBrfeU8f+03SFdhVmJKQl 25 | uaWCtQFmBaVGPH2LDmLItGC+XvjLG3us1lkihRWF06lzY5puNIZav91QkPFtOM343cFMQv 26 | tP6KmrQ4PIj0iBWnAAAAE21hcmlhbm9AZW5kb3IubG9jYWwBAgMEBQYH 27 | -----END OPENSSH PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /pemutil/testdata/openssh.rsa2048.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDmbvmkzG 3 | Ta/0HnswjwUhe6AAAAEAAAAAEAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQCum4bMH4Bm 4 | /vkPlk/qbBMrFlYUzVlUQnsBYunNREZb7itdBRau9nujSYhTbdtwMgH0gEnXp9gj/Hcvz3 5 | YdGYM/cOXZ334CbmTQ0cqiV90d2Qf03zDZS7ezv7Kamq0vdkA0Npw5lTOmZKnQcNibBAqc 6 | p2BeKSDIYGMTZMsEHOHsPX9jdwpEU4QevKAszjTF/UaPNLVpfMsEPuV9D8l02GPVg8HZXM 7 | NZt483nnN3MMnEqIuqRurEHz7xS9U5Rtqf45cQeFEcDXJa2ggVmLVfpHim4qHReA3qSz5Q 8 | igvAR0I3XrBKv5MhLH0NPDawzeAgF0HR18CAkp+/KAP3CA6FXWWtAAAD0J99ooy+BJRWof 9 | GqhVwTk/5c0fZvg/sWITECrfkobVfDvZy29xVImR/sx9hJ9cTQgISA3zbtMVFX909lTQsZ 10 | sHTKT8zknwF4KQaiKeItoF4xJSp6YhTsbPt8HocrWNdnP1CI5lF5NqQllKncTTfNmRYLTD 11 | +MGn8dfXW8wd/SLT/XRLNvZ+C9QfxRXjZyoV7EBtxRFFMelTsx3cW0tJAI5gYPmB4m7M2t 12 | zXEy9gI1+eOWWc6cJ/i/7nbb7BmTNQ/iwfAPrnmtu/rPbvjSsXiJZ3ZoC718hb2hM0UmDv 13 | Z3lkE0nL2Z6BR0Et0s7dMUbbQS1QXpUyZ2yTuRUxke/wUbcVQ4whJ8f26VdKN4L9+jTU59 14 | cmmMfCaFUHS/sswt+5enmRjilLTfSbtzhqRBsKmWFrvw3c0/CAgVzuDpxj5fwtFDm4V3i6 15 | hyNZR6IK1LLUM7g7B5utE3E9pbi3JZiFroAGmM+68cmiASzWUpvdvW37evpGXZIJ6KOrRj 16 | X28bhR8p7C6uXOTU4AOkSGFHxShtMtkDuV65jSu4CQo+e/TII0VnzsAACUj5EEeY0Jh36Z 17 | 0tWbmgJKVqCeQLQs6ydJFofho7cmGCSIXpPg1Rg39WJeI/UgRkNzeEdqBbUro3BifpYeFG 18 | WlA7V8DmFtJIHyjUC/FiujPFU4Y/XIJb+2Sfb8HV08fN0jwC5FUStZ73nXVkkheLtjM1yA 19 | 3DXYWGec7Dt9sVCZ2nEls3Z+mG87QKCNubPzbDok+MWk/Ts/xGA/O7TDUWQ9lZR5NEQ/QY 20 | NneNafeu5seA8hixcPWpam28SnBD5e3o8iph/YC7l2qRwlFjiPmzLmkYuyWcX6EXUrG9mE 21 | sf4H7tUjIO6OPrmkVlANxGVsgQdq0TyeCEnygYkaZpMq8hWy/OCys+ukZOXOD6DsUC0EfI 22 | bFQ3CbHr53aoTw3HqwtQ5usAa68wEfP8TJUVba4+L6EDxRIZokX+qEur/fVBBd/nQQiBVD 23 | mMq4WghC0x7VubOAApiBGjHSBlAhf0GDuZx1Lcr9BWsUPuI03jawMdlXZjZ85/Q2FvawuB 24 | Ycp5Nq1/mnmywPjxqlmJ3GbMXlM1x8P8Tg1AK8geQaqRYrOh6B168ZWoYpaGms0BABrTwh 25 | vzjzQMy6aUhQx0jMTHvswI4xmFOGi5vFxl4xc33bHp/hNchcc2qJ6fFRm98uIXgh4NpiwF 26 | 3YjB1I8pyGUusPvOodiLt3PX4H1qpow4ReytIYF3OOCS2dQ8sxQpmcNA58JVoZZrdnFXOb 27 | kSITa1p1NwHbm2PAzaZE0XBkHA+fI= 28 | -----END OPENSSH PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /internal/utils/convert/convert_test.go: -------------------------------------------------------------------------------- 1 | package convert 2 | 3 | import ( 4 | "math" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestMustUint64ConvertsValues(t *testing.T) { 11 | require.Equal(t, uint64(0), MustUint64(0)) 12 | require.Equal(t, uint64(math.MaxInt64), MustUint64(int64(math.MaxInt64))) 13 | require.Equal(t, uint64(42), MustUint64(42)) 14 | } 15 | 16 | func TestMustUint64PanicsOnNegativeValue(t *testing.T) { 17 | require.Panics(t, func() { MustUint64(-1) }) 18 | } 19 | 20 | func TestMustUint32ConvertsValues(t *testing.T) { 21 | require.Equal(t, uint32(0), MustUint32(0)) 22 | require.Equal(t, uint32(math.MaxUint32), MustUint32(int64(math.MaxUint32))) 23 | require.Equal(t, uint32(42), MustUint32(42)) 24 | } 25 | 26 | func TestMustUint32PanicsOnNegativeValue(t *testing.T) { 27 | require.Panics(t, func() { MustUint32(-1) }) 28 | } 29 | 30 | func TestMustUint32PanicsOnLargeValue(t *testing.T) { 31 | require.Panics(t, func() { MustUint32(int64(math.MaxUint32 + 1)) }) 32 | } 33 | 34 | func TestMustUint16ConvertsValues(t *testing.T) { 35 | require.Equal(t, uint16(0), MustUint16(0)) 36 | require.Equal(t, uint16(math.MaxUint16), MustUint16(math.MaxUint16)) 37 | require.Equal(t, uint16(42), MustUint16(42)) 38 | } 39 | 40 | func TestMustUint16PanicsOnNegativeValue(t *testing.T) { 41 | require.Panics(t, func() { MustUint16(-1) }) 42 | } 43 | 44 | func TestMustUint16PanicsOnLargeValue(t *testing.T) { 45 | require.Panics(t, func() { MustUint16(math.MaxUint16 + 1) }) 46 | } 47 | 48 | func TestMustUint8ConvertsValues(t *testing.T) { 49 | require.Equal(t, uint8(0), MustUint8(0)) 50 | require.Equal(t, uint8(math.MaxUint8), MustUint8(math.MaxUint8)) 51 | require.Equal(t, uint8(42), MustUint8(42)) 52 | } 53 | 54 | func TestMustUint8PanicsOnNegativeValue(t *testing.T) { 55 | require.Panics(t, func() { MustUint8(-1) }) 56 | } 57 | 58 | func TestMustUint8PanicsOnLargeValue(t *testing.T) { 59 | require.Panics(t, func() { MustUint8(math.MaxUint8 + 1) }) 60 | } 61 | -------------------------------------------------------------------------------- /pemutil/testdata/pkcs8/openssl.rsa2048.enc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED PRIVATE KEY----- 2 | MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIG+MeTStZSz8CAggA 3 | MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBDl6AHXEtGaJzi08s/85HIpBIIE 4 | 0M4fBopP+Mwj8kJzXge0/FGm8gbug9wl4OFsfvKQRpZyt8g9WJsw3jjI47kiIQt5 5 | 8fnrIiB08Eu1GkWxS/gBkVJkSfG7Ac90Tx4Xr+KheysG8aODUNPBSdt1NLc1wWen 6 | qiInky0IXG2+SUU5s5rmQ45RFBeYTZD3mipyt1vVF5jIfaD1xooA1CoIIwxZ1uHZ 7 | zbrV+pYGYxHjJUJtDMOQQbOwenPREznVdpIFNM/PfRcR9BzFONkA2y75Onn8U4sg 8 | yqvCjzf1gMGFGh6s/52iddjMsi7CIkBV7SyFw4uBowrgaYd1hXW0pN84EC5psdAV 9 | k1AzR9sLpcv7KJOy15qgm9Tz24J+TwQ4DMo8BFGdxHxyTbcQcxbqu38NlSp/LENs 10 | SVh/hOrUxwqAnVoDHCb6+wnTKa/gdmMt0tFvn+nUsjgDMwXrluyc2UxCeKfzfmCs 11 | jyGF5SLh1nKxuZv+7lAPP1VlCkUEdPw3RUaybOjkkd3a30n8Dcl1425LlIdaB1FK 12 | n0aK+wzwOzbmMX1v481W4CYHWScvit8kaucZ7sEomvACLOTF3J4pEYy7AZoDe4AQ 13 | zEA7aPRp67uoAFWAABlbK9O5w+bL2TBZpIGSlrMKRP2cLWANaZkWMPgXtVGKFFOO 14 | +qB+IYDOKpxf1T186QDMQeh8o/d5xLqlynw20DE4jm+qCeGGmNZbIe53/Flj7Asw 15 | dlQP2+wXQdFVlyZ7vLIqyVEJ+tZS/8Jjo1mNZLdnesNsNzH0KKb4lYfx/fXjorXG 16 | YHOzfRGrwkn9RsH6A074X0Z6KJzsDR0wrPXBB0K4MsR4LQzJdkgBdJ2hXFuuitOB 17 | Gy0mdPE6Mo4vpS499uyqDs2Fh3sodsVKz15+QRnrk6RNQ5ydqb8nrydQsG0ZEXQU 18 | 2VnfN2R5rHv4KlUbyRxZWxeP1IRlkMFjpXpXzjMIsmye2M7DCGkjPVyd5i5ulS33 19 | kHPQd+L7EWRpUDYLrzRDnslDSNwdhNuYd2kiDkGWf3hXrRjeMBUbCLfQBPZi/o2O 20 | AIb1+60ItjA9koDjWd9ppvz4N9d8Mnb5Watz4El/Uuj24rmNxEautNO4nQfyt5FS 21 | 2dIo4+MG/QqnOq1Q8NACeSwyHqvjS4F032XlwpPsaWhM0TSVxt1E3xVUVJ4Vebp2 22 | jC52o5/Awifjlg7wHWRqqi3gVwdTshIsOUQspD9c2Sa8x0wbQM6lKDmm6b4s1mlX 23 | ETkTSXlxJcfYzFQVdFMSd6qvWVj2oN/gWfSB7w7n6SqVS9G7858bCtNVBQPmN4RS 24 | GAe5dZSN65Q6LtRcDDz3ttNjxasjsbeB986t/9h5fb4D+iRM7c7qIpd2U0frT3sY 25 | p31gC0F1spwdTiJ3yW46q3m7MUXThMjqWAvP0OEIO4z71oezIhWfk9eiGnkuJUIh 26 | r+B7rpbLkYpi8gEtiq4FTZoqgX1rbxcgAtMyQwdsUfZHp9zR42zs+XtXJdaHrb12 27 | hb+D8pmc/FY33ApsioJOv/QjQC8eRUfu+6AQu4AUhgIH0YfO9LD8eMRsCaYrX5ac 28 | P1IV0xBBrrnmnTacFrjtEw4k4YdAKPO8v/x41PP9zeHcuAfQ4Zi7RS3ea3qey6C3 29 | 6GoB3zuOG68yUYu5eSbDnctX1JnXNFCqxFB26fHiv33Q 30 | -----END ENCRYPTED PRIVATE KEY----- 31 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Set V to 1 for verbose output from the Makefile 2 | Q=$(if $V,,@) 3 | SRC=$(shell find . -type f -name '*.go') 4 | 5 | all: lint test 6 | 7 | ci: test 8 | 9 | .PHONY: all ci 10 | 11 | ######################################### 12 | # Bootstrapping 13 | ######################################### 14 | 15 | bootstra%: 16 | $Q curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin latest 17 | $Q go install golang.org/x/vuln/cmd/govulncheck@latest 18 | $Q go install gotest.tools/gotestsum@latest 19 | 20 | .PHONY: bootstrap 21 | 22 | ######################################### 23 | # Test 24 | ######################################### 25 | 26 | test: defaulttest simulatortest combinecoverage 27 | 28 | defaulttest: 29 | $Q $(GOFLAGS) gotestsum -- -coverpkg=./... -coverprofile=defaultcoverage.out -covermode=atomic ./... 30 | 31 | simulatortest: 32 | $Q $(GOFLAGS) CGO_ENABLED=1 gotestsum -- -coverpkg=./tpm/...,./kms/tpmkms -coverprofile=simulatorcoverage.out -covermode=atomic -tags tpmsimulator ./tpm ./kms/tpmkms 33 | 34 | combinecoverage: 35 | cat defaultcoverage.out > coverage.out 36 | tail -n +2 simulatorcoverage.out >> coverage.out 37 | 38 | race: 39 | $Q $(GOFLAGS) gotestsum -- -race ./... 40 | 41 | .PHONY: test defaulttest simulatortest combinecoverage race 42 | 43 | ######################################### 44 | # Linting 45 | ######################################### 46 | 47 | fmt: 48 | $Q goimports -l -w $(SRC) 49 | 50 | lint: golint govulncheck 51 | 52 | golint: SHELL:=/bin/bash 53 | golint: 54 | $Q LOG_LEVEL=error golangci-lint run --config <(curl -s https://raw.githubusercontent.com/smallstep/workflows/main/.golangci.yml) --timeout=30m 55 | 56 | govulncheck: 57 | $Q govulncheck ./... 58 | 59 | .PHONY: fmt lint golint govulncheck 60 | 61 | ######################################### 62 | # Go generate 63 | ######################################### 64 | 65 | generate: 66 | $Q go generate ./... 67 | 68 | .PHONY: generate 69 | -------------------------------------------------------------------------------- /x509util/fingerprint.go: -------------------------------------------------------------------------------- 1 | package x509util 2 | 3 | import ( 4 | "crypto/sha256" 5 | "crypto/x509" 6 | 7 | "go.step.sm/crypto/fingerprint" 8 | ) 9 | 10 | // FingerprintEncoding defines the supported encodings in certificate 11 | // fingerprints. 12 | type FingerprintEncoding = fingerprint.Encoding 13 | 14 | // Supported fingerprint encodings. 15 | const ( 16 | // DefaultFingerprint represents the hex encoding of the fingerprint. 17 | DefaultFingerprint = FingerprintEncoding(0) 18 | // HexFingerprint represents the hex encoding of the fingerprint. 19 | HexFingerprint = fingerprint.HexFingerprint 20 | // Base64Fingerprint represents the base64 encoding of the fingerprint. 21 | Base64Fingerprint = fingerprint.Base64Fingerprint 22 | // Base64URLFingerprint represents the base64URL encoding of the fingerprint. 23 | Base64URLFingerprint = fingerprint.Base64URLFingerprint 24 | // Base64RawFingerprint represents the base64RawStd encoding of the fingerprint. 25 | Base64RawFingerprint = fingerprint.Base64RawFingerprint 26 | // Base64RawURLFingerprint represents the base64RawURL encoding of the fingerprint. 27 | Base64RawURLFingerprint = fingerprint.Base64RawURLFingerprint 28 | // EmojiFingerprint represents the emoji encoding of the fingerprint. 29 | EmojiFingerprint = fingerprint.EmojiFingerprint 30 | ) 31 | 32 | // Fingerprint returns the SHA-256 fingerprint of the certificate. 33 | func Fingerprint(cert *x509.Certificate) string { 34 | return EncodedFingerprint(cert, DefaultFingerprint) 35 | } 36 | 37 | // EncodedFingerprint returns the SHA-256 hash of the certificate using the 38 | // specified encoding. If an invalid encoding is passed, the return value will 39 | // be an empty string. 40 | func EncodedFingerprint(cert *x509.Certificate, encoding FingerprintEncoding) string { 41 | sum := sha256.Sum256(cert.Raw) 42 | switch encoding { 43 | case DefaultFingerprint: 44 | return fingerprint.Fingerprint(sum[:], HexFingerprint) 45 | default: 46 | return fingerprint.Fingerprint(sum[:], encoding) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /x509util/testdata/smallstep.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFZTCCBE2gAwIBAgISBPRFhEdtcBsNSxHgkoSkHpU/MA0GCSqGSIb3DQEBCwUA 3 | MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD 4 | ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0yMDA2MTYwNzE2NTZaFw0y 5 | MDA5MTQwNzE2NTZaMBoxGDAWBgNVBAMMDyouc21hbGxzdGVwLmNvbTCCASIwDQYJ 6 | KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMgKbXAbD84RScmR3QGVlT27U09ihM6X 7 | XkVp4Ht4fbfm2SvpmOm7kLt5EB3f+0/I3enVsupCoULisUOQpEaoY9wXTjSHRSKl 8 | X3QPzyb8eJrwltxeo0qC5SidaVl2lXcSpKrKMvbp5qfd4hLhAJudEldmTFMQjzou 9 | /FouhzDpP4UDzf8Kc9b8Px27Qw7hg/888lJwCIcTAIVgmHUOxZKmjsHe0rHTNTYi 10 | mE+76udBPyG/Kis+ld2nuufqI/gPrD6gkm5pqSekt057zbk9oJTdBZTuAtaPGlER 11 | bH4G4fbkoT6j0tD7qafeebKATGBtzsK8gqwTZ2Uh4jzd5Ppukg2x4gkCAwEAAaOC 12 | AnMwggJvMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB 13 | BQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUFlxnRkxa25R8P1zsLqtVMHBC 14 | MlUwHwYDVR0jBBgwFoAUqEpqYwR93brm0Tm3pkVl7/Oo7KEwbwYIKwYBBQUHAQEE 15 | YzBhMC4GCCsGAQUFBzABhiJodHRwOi8vb2NzcC5pbnQteDMubGV0c2VuY3J5cHQu 16 | b3JnMC8GCCsGAQUFBzAChiNodHRwOi8vY2VydC5pbnQteDMubGV0c2VuY3J5cHQu 17 | b3JnLzApBgNVHREEIjAggg8qLnNtYWxsc3RlcC5jb22CDXNtYWxsc3RlcC5jb20w 18 | TAYDVR0gBEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC3xMBAQEwKDAmBggrBgEFBQcC 19 | ARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEEBgorBgEEAdZ5AgQCBIH1 20 | BIHyAPAAdgDwlaRZ8gDRgkAQLS+TiI6tS/4dR+OZ4dA0prCoqo6ycwAAAXK8M+PT 21 | AAAEAwBHMEUCIFjO361bM1BiXp9Nexw1KxJX34bI98JkBsHkSz3S+nSZAiEAuBy6 22 | KBUpYNLT71aPoVWtprZnxThUmKq2gm2Jltp5gMgAdgCyHgXMi6LNiiBOh2b5K7mK 23 | JSBna9r6cOeySVMt74uQXgAAAXK8M+PAAAAEAwBHMEUCIQCIqfGGfeGQHtYnVO4J 24 | UPTqIbNia+Lrbfw9HARElQw4iAIgSspUzNwYHY4cU/BdpfHRaTGzddrTFXhEoCQt 25 | 0pbaG0wwDQYJKoZIhvcNAQELBQADggEBAJJgEB70PUChWsbLUyFk1udDPePanU5O 26 | zzSViB5+fesWppG9IDnYnL6KSI+l1jP9jl5Zym79SQ2gSC3xwkswpT8X+Drzup/7 27 | UV7T5NbHpzkZfg2itsx407yuxoW2L7zihZ4CWm1bodUbPKWNYJAZFrcxqcydwmFn 28 | pvZMoJDP3PW0hejz+gsLe9ZrtXb8q1BLFupHfx+bTx476qhRyL+e2fDi5wQz1Qs2 29 | jVZGsvv/cljvlRSLZ0NVPeKcRN50f7UQ7OYw+JLR2K5+K1H7oHiu+iUX4F2/PGGm 30 | Tb4HBKgzkJSsS5b3pEp+2U77m9KOBhsiZOVvQ2ECgJ9/eDiy0QCqEyI= 31 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /tlsutil/utils_test.go: -------------------------------------------------------------------------------- 1 | package tlsutil 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSanitizeName(t *testing.T) { 8 | type args struct { 9 | domain string 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want string 15 | wantErr bool 16 | }{ 17 | {"ok", args{"smallstep.com"}, "smallstep.com", false}, 18 | {"ok ascii", args{"bücher.example.com"}, "xn--bcher-kva.example.com", false}, 19 | {"fail", args{"xn--bücher.example.com"}, "", true}, 20 | {"fail empty", args{""}, "", true}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | got, err := SanitizeName(tt.args.domain) 25 | if (err != nil) != tt.wantErr { 26 | t.Errorf("SanitizeName() error = %v, wantErr %v", err, tt.wantErr) 27 | return 28 | } 29 | if got != tt.want { 30 | t.Errorf("SanitizeName() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | 36 | func TestSanitizeHost(t *testing.T) { 37 | type args struct { 38 | host string 39 | } 40 | tests := []struct { 41 | name string 42 | args args 43 | want string 44 | wantErr bool 45 | }{ 46 | {"ok", args{"smallstep.com"}, "smallstep.com", false}, 47 | {"ok port", args{"smallstep.com:443"}, "smallstep.com", false}, 48 | {"ok ascii", args{"bücher.example.com"}, "xn--bcher-kva.example.com", false}, 49 | {"ok ascii port", args{"bücher.example.com:443"}, "xn--bcher-kva.example.com", false}, 50 | {"fail", args{"xn--bücher.example.com"}, "", true}, 51 | {"fail port", args{"xn--bücher.example.com:443"}, "", true}, 52 | {"fail empty", args{""}, "", true}, 53 | {"fail empty with port", args{":443"}, "", true}, 54 | } 55 | for _, tt := range tests { 56 | t.Run(tt.name, func(t *testing.T) { 57 | got, err := SanitizeHost(tt.args.host) 58 | if (err != nil) != tt.wantErr { 59 | t.Errorf("SanitizeHost() error = %v, wantErr %v", err, tt.wantErr) 60 | return 61 | } 62 | if got != tt.want { 63 | t.Errorf("SanitizeHost() = %v, want %v", got, tt.want) 64 | } 65 | }) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tpm/storage/types_test.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "crypto/x509" 5 | "encoding/json" 6 | "testing" 7 | "time" 8 | 9 | "github.com/stretchr/testify/require" 10 | 11 | "go.step.sm/crypto/keyutil" 12 | "go.step.sm/crypto/minica" 13 | "go.step.sm/crypto/x509util" 14 | ) 15 | 16 | func TestAK_MarshalUnmarshal(t *testing.T) { 17 | ca, err := minica.New() 18 | require.NoError(t, err) 19 | 20 | signer, err := keyutil.GenerateSigner("RSA", "", 2048) 21 | require.NoError(t, err) 22 | 23 | cr, err := x509util.NewCertificateRequest(signer) 24 | require.NoError(t, err) 25 | cr.Subject.CommonName = "testak" 26 | 27 | csr, err := cr.GetCertificateRequest() 28 | require.NoError(t, err) 29 | 30 | cert, err := ca.SignCSR(csr) 31 | require.NoError(t, err) 32 | 33 | ak := &AK{ 34 | Name: "ak1", 35 | Data: []byte{1, 2, 3, 4}, 36 | Chain: []*x509.Certificate{cert, ca.Intermediate}, 37 | CreatedAt: time.Time{}, 38 | } 39 | 40 | data, err := json.Marshal(ak) 41 | require.NoError(t, err) 42 | 43 | var rak = &AK{} 44 | err = json.Unmarshal(data, rak) 45 | require.NoError(t, err) 46 | require.Equal(t, ak, rak) 47 | } 48 | 49 | func TestKey_MarshalUnmarshal(t *testing.T) { 50 | ca, err := minica.New() 51 | require.NoError(t, err) 52 | 53 | signer, err := keyutil.GenerateSigner("RSA", "", 2048) 54 | require.NoError(t, err) 55 | 56 | cr, err := x509util.NewCertificateRequest(signer) 57 | require.NoError(t, err) 58 | cr.Subject.CommonName = "testkey" 59 | 60 | csr, err := cr.GetCertificateRequest() 61 | require.NoError(t, err) 62 | 63 | cert, err := ca.SignCSR(csr) 64 | require.NoError(t, err) 65 | 66 | key := &Key{ 67 | Name: "key1", 68 | Data: []byte{1, 2, 3, 4}, 69 | AttestedBy: "ak1", 70 | Chain: []*x509.Certificate{cert, ca.Intermediate}, 71 | CreatedAt: time.Time{}, 72 | } 73 | 74 | data, err := json.Marshal(key) 75 | require.NoError(t, err) 76 | 77 | var rkey = &Key{} 78 | err = json.Unmarshal(data, rkey) 79 | require.NoError(t, err) 80 | require.Equal(t, key, rkey) 81 | } 82 | -------------------------------------------------------------------------------- /kms/uri/uri_other_test.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.19 2 | 3 | package uri 4 | 5 | import ( 6 | "net/url" 7 | "reflect" 8 | "testing" 9 | ) 10 | 11 | func TestParse(t *testing.T) { 12 | type args struct { 13 | rawuri string 14 | } 15 | tests := []struct { 16 | name string 17 | args args 18 | want *URI 19 | wantErr bool 20 | }{ 21 | {"ok", args{"yubikey:slot-id=9a"}, &URI{ 22 | URL: &url.URL{Scheme: "yubikey", Opaque: "slot-id=9a"}, 23 | Values: url.Values{"slot-id": []string{"9a"}}, 24 | }, false}, 25 | {"ok schema", args{"cloudkms:"}, &URI{ 26 | URL: &url.URL{Scheme: "cloudkms"}, 27 | Values: url.Values{}, 28 | }, false}, 29 | {"ok query", args{"yubikey:slot-id=9a;foo=bar?pin=123456&foo=bar"}, &URI{ 30 | URL: &url.URL{Scheme: "yubikey", Opaque: "slot-id=9a;foo=bar", RawQuery: "pin=123456&foo=bar"}, 31 | Values: url.Values{"slot-id": []string{"9a"}, "foo": []string{"bar"}}, 32 | }, false}, 33 | {"ok file", args{"file:///tmp/ca.cert"}, &URI{ 34 | URL: &url.URL{Scheme: "file", Path: "/tmp/ca.cert"}, 35 | Values: url.Values{}, 36 | }, false}, 37 | {"ok file simple", args{"file:/tmp/ca.cert"}, &URI{ 38 | URL: &url.URL{Scheme: "file", Path: "/tmp/ca.cert"}, 39 | Values: url.Values{}, 40 | }, false}, 41 | {"ok file host", args{"file://tmp/ca.cert"}, &URI{ 42 | URL: &url.URL{Scheme: "file", Host: "tmp", Path: "/ca.cert"}, 43 | Values: url.Values{}, 44 | }, false}, 45 | {"fail schema", args{"cloudkms"}, nil, true}, 46 | {"fail parse", args{"yubi%key:slot-id=9a"}, nil, true}, 47 | {"fail scheme", args{"yubikey"}, nil, true}, 48 | {"fail parse opaque", args{"yubikey:slot-id=%ZZ"}, nil, true}, 49 | } 50 | for _, tt := range tests { 51 | t.Run(tt.name, func(t *testing.T) { 52 | got, err := Parse(tt.args.rawuri) 53 | if (err != nil) != tt.wantErr { 54 | t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr) 55 | return 56 | } 57 | if !reflect.DeepEqual(got, tt.want) { 58 | t.Errorf("Parse() = %#v, want %#v", got.URL, tt.want.URL) 59 | } 60 | }) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /kms/uri/uri_119_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.19 2 | 3 | package uri 4 | 5 | import ( 6 | "net/url" 7 | "reflect" 8 | "testing" 9 | ) 10 | 11 | func TestParse(t *testing.T) { 12 | type args struct { 13 | rawuri string 14 | } 15 | tests := []struct { 16 | name string 17 | args args 18 | want *URI 19 | wantErr bool 20 | }{ 21 | {"ok", args{"yubikey:slot-id=9a"}, &URI{ 22 | URL: &url.URL{Scheme: "yubikey", Opaque: "slot-id=9a"}, 23 | Values: url.Values{"slot-id": []string{"9a"}}, 24 | }, false}, 25 | {"ok schema", args{"cloudkms:"}, &URI{ 26 | URL: &url.URL{Scheme: "cloudkms"}, 27 | Values: url.Values{}, 28 | }, false}, 29 | {"ok query", args{"yubikey:slot-id=9a;foo=bar?pin=123456&foo=bar"}, &URI{ 30 | URL: &url.URL{Scheme: "yubikey", Opaque: "slot-id=9a;foo=bar", RawQuery: "pin=123456&foo=bar"}, 31 | Values: url.Values{"slot-id": []string{"9a"}, "foo": []string{"bar"}}, 32 | }, false}, 33 | {"ok file", args{"file:///tmp/ca.cert"}, &URI{ 34 | URL: &url.URL{Scheme: "file", Path: "/tmp/ca.cert"}, 35 | Values: url.Values{}, 36 | }, false}, 37 | {"ok file simple", args{"file:/tmp/ca.cert"}, &URI{ 38 | URL: &url.URL{Scheme: "file", Path: "/tmp/ca.cert", OmitHost: true}, 39 | Values: url.Values{}, 40 | }, false}, 41 | {"ok file host", args{"file://tmp/ca.cert"}, &URI{ 42 | URL: &url.URL{Scheme: "file", Host: "tmp", Path: "/ca.cert"}, 43 | Values: url.Values{}, 44 | }, false}, 45 | {"fail schema", args{"cloudkms"}, nil, true}, 46 | {"fail parse", args{"yubi%key:slot-id=9a"}, nil, true}, 47 | {"fail scheme", args{"yubikey"}, nil, true}, 48 | {"fail parse opaque", args{"yubikey:slot-id=%ZZ"}, nil, true}, 49 | } 50 | for _, tt := range tests { 51 | t.Run(tt.name, func(t *testing.T) { 52 | got, err := Parse(tt.args.rawuri) 53 | if (err != nil) != tt.wantErr { 54 | t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr) 55 | return 56 | } 57 | if !reflect.DeepEqual(got, tt.want) { 58 | t.Errorf("Parse() = %#v, want %#v", got.URL, tt.want.URL) 59 | } 60 | }) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /internal/utils/convert/convert.go: -------------------------------------------------------------------------------- 1 | package convert 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | type integer interface { 9 | ~int | ~int64 10 | } 11 | 12 | // SafeUint64 converts an integer value to [uint64]. It returns an error if the value is out of range. 13 | func SafeUint64[T integer](x T) (uint64, error) { 14 | if x < 0 { 15 | return 0, fmt.Errorf("value %d out of range for uint64", x) 16 | } 17 | 18 | return uint64(x), nil 19 | } 20 | 21 | // MustUint64 converts an integer value to [uint64]. It panics if the value is out of range. 22 | func MustUint64[T integer](x T) uint64 { 23 | u64, err := SafeUint64(x) 24 | if err != nil { 25 | panic(err) 26 | } 27 | 28 | return u64 29 | } 30 | 31 | // SafeUint32 converts an integer value to [uint32]. It returns an error if the value is out of range. 32 | func SafeUint32[T integer](x T) (uint32, error) { 33 | if x < 0 || int64(x) > math.MaxUint32 { 34 | return 0, fmt.Errorf("value %d out of range for uint32", x) 35 | } 36 | 37 | return uint32(x), nil 38 | } 39 | 40 | // MustUint32 converts an integer value to [uint32]. It panics if the value is out of range. 41 | func MustUint32[T integer](x T) uint32 { 42 | u32, err := SafeUint32(x) 43 | if err != nil { 44 | panic(err) 45 | } 46 | 47 | return u32 48 | } 49 | 50 | // MustUint16 converts an integer value to [uint16]. It panics if the value is out of range. 51 | func MustUint16(x int) uint16 { 52 | if x < 0 || x > math.MaxUint16 { 53 | panic(fmt.Errorf("value %d out of range for uint16", x)) 54 | } 55 | 56 | return uint16(x) 57 | } 58 | 59 | // SafeUint8 converts an integer value to [uint8]. It returns an error if the value is out of range. 60 | func SafeUint8(x int) (uint8, error) { 61 | if x < 0 || x > math.MaxUint8 { 62 | return 0, fmt.Errorf("value %d out of range for uint8", x) 63 | } 64 | 65 | return uint8(x), nil 66 | } 67 | 68 | // MustUint8 converts an integer value to [uint8]. It panics if the value is out of range. 69 | func MustUint8(x int) uint8 { 70 | u8, err := SafeUint8(x) 71 | if err != nil { 72 | panic(err) 73 | } 74 | 75 | return u8 76 | } 77 | -------------------------------------------------------------------------------- /tpm/tss2/encode.go: -------------------------------------------------------------------------------- 1 | package tss2 2 | 3 | import ( 4 | "encoding/pem" 5 | 6 | "github.com/google/go-tpm/tpmutil" 7 | ) 8 | 9 | // handleOwner is the reserved handle TPM_RH_OWNER. 10 | const handleOwner = tpmutil.Handle(0x40000001) 11 | 12 | // TPMOption is the type used to modify a [TPMKey]. 13 | type TPMOption func(*TPMKey) 14 | 15 | // WithParent sets the [TPMKey] parent handle. 16 | func WithParent(parent tpmutil.Handle) TPMOption { 17 | return func(t *TPMKey) { 18 | t.Parent = int(parent) 19 | } 20 | } 21 | 22 | // New creates a new [TPMKey] with the given public and private keys. 23 | func New(pub, priv []byte, opts ...TPMOption) *TPMKey { 24 | key := &TPMKey{ 25 | Type: oidLoadableKey, 26 | EmptyAuth: true, 27 | Parent: int(handleOwner), 28 | PublicKey: addPrefixLength(pub), 29 | PrivateKey: addPrefixLength(priv), 30 | } 31 | for _, fn := range opts { 32 | fn(key) 33 | } 34 | return key 35 | } 36 | 37 | // Encode encodes the [TPMKey] returns a [*pem.Block]. 38 | func (k *TPMKey) Encode() (*pem.Block, error) { 39 | b, err := MarshalPrivateKey(k) 40 | if err != nil { 41 | return nil, err 42 | } 43 | return &pem.Block{ 44 | Type: "TSS2 PRIVATE KEY", 45 | Bytes: b, 46 | }, nil 47 | } 48 | 49 | // EncodeToMemory encodes the [TPMKey] and returns an encoded PEM block. 50 | func (k *TPMKey) EncodeToMemory() ([]byte, error) { 51 | block, err := k.Encode() 52 | if err != nil { 53 | return nil, err 54 | } 55 | return pem.EncodeToMemory(block), nil 56 | } 57 | 58 | // Encode encodes the given public and private key and returns a [*pem.Block]. 59 | func Encode(pub, priv []byte, opts ...TPMOption) (*pem.Block, error) { 60 | return New(pub, priv, opts...).Encode() 61 | } 62 | 63 | // EncodeToMemory encodes the given public and private key and returns an 64 | // encoded PEM block. 65 | func EncodeToMemory(pub, priv []byte, opts ...TPMOption) ([]byte, error) { 66 | return New(pub, priv, opts...).EncodeToMemory() 67 | } 68 | 69 | func addPrefixLength(b []byte) []byte { 70 | s := len(b) 71 | return append([]byte{byte(s >> 8 & 0xFF), byte(s & 0xFF)}, b...) 72 | } 73 | -------------------------------------------------------------------------------- /sshutil/types.go: -------------------------------------------------------------------------------- 1 | package sshutil 2 | 3 | import ( 4 | "encoding/json" 5 | "strings" 6 | 7 | "github.com/pkg/errors" 8 | "golang.org/x/crypto/ssh" 9 | ) 10 | 11 | // CertType defines the certificate type, it can be a user or a host 12 | // certificate. 13 | type CertType uint32 14 | 15 | const ( 16 | // UserCert defines a user certificate. 17 | UserCert CertType = ssh.UserCert 18 | 19 | // HostCert defines a host certificate. 20 | HostCert CertType = ssh.HostCert 21 | ) 22 | 23 | const ( 24 | userString = "user" 25 | hostString = "host" 26 | ) 27 | 28 | // CertTypeFromString returns the CertType for the string "user" and "host". 29 | func CertTypeFromString(s string) (CertType, error) { 30 | switch strings.ToLower(s) { 31 | case userString: 32 | return UserCert, nil 33 | case hostString: 34 | return HostCert, nil 35 | default: 36 | return 0, errors.Errorf("unknown certificate type '%s'", s) 37 | } 38 | } 39 | 40 | // String returns "user" for user certificates and "host" for host certificates. 41 | // It will return the empty string for any other value. 42 | func (c CertType) String() string { 43 | switch c { 44 | case UserCert: 45 | return userString 46 | case HostCert: 47 | return hostString 48 | default: 49 | return "" 50 | } 51 | } 52 | 53 | // MarshalJSON implements the json.Marshaler interface for CertType. UserCert 54 | // will be marshaled as the string "user" and HostCert as "host". 55 | func (c CertType) MarshalJSON() ([]byte, error) { 56 | if s := c.String(); s != "" { 57 | return []byte(`"` + s + `"`), nil 58 | } 59 | return nil, errors.Errorf("unknown certificate type %d", c) 60 | } 61 | 62 | // UnmarshalJSON implements the json.Unmarshaler interface for CertType. 63 | func (c *CertType) UnmarshalJSON(data []byte) error { 64 | var s string 65 | if err := json.Unmarshal(data, &s); err != nil { 66 | return errors.Wrap(err, "error unmarshaling certificate type") 67 | } 68 | certType, err := CertTypeFromString(s) 69 | if err != nil { 70 | return errors.Errorf("error unmarshaling '%s' as a certificate type", s) 71 | } 72 | *c = certType 73 | return nil 74 | } 75 | -------------------------------------------------------------------------------- /tpm/caps.go: -------------------------------------------------------------------------------- 1 | package tpm 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "slices" 7 | 8 | "github.com/google/go-tpm/legacy/tpm2" 9 | "go.step.sm/crypto/tpm/algorithm" 10 | ) 11 | 12 | // Capabilities represents the capabilities of the TPM. 13 | type Capabilities struct { 14 | Algorithms []algorithm.Algorithm 15 | } 16 | 17 | // SupportsAlgorithm return whether the provided algorithm 18 | // is supported by the TPM 19 | func (c *Capabilities) SupportsAlgorithm(alg algorithm.Algorithm) bool { 20 | return slices.Contains(c.Algorithms, alg) 21 | } 22 | 23 | // SupportsAlgorithms return whether all algorithms in the provided 24 | // slice are supported by the TPM 25 | func (c *Capabilities) SupportsAlgorithms(algs []algorithm.Algorithm) bool { 26 | for _, alg := range algs { 27 | if !c.SupportsAlgorithm(alg) { 28 | return false 29 | } 30 | } 31 | return true 32 | } 33 | 34 | // GetCapabilities returns the capabilities of the TPM; currently suports 35 | // enumerating the supported algorithms 36 | // 37 | // Notice: This API is EXPERIMENTAL and may be changed or removed in a later 38 | // release. 39 | func (t *TPM) GetCapabilities(ctx context.Context) (caps *Capabilities, err error) { 40 | if t.caps != nil { 41 | return t.caps, nil 42 | } 43 | 44 | if err = t.open(goTPMCall(ctx)); err != nil { 45 | return nil, fmt.Errorf("failed opening TPM: %w", err) 46 | } 47 | defer closeTPM(ctx, t, &err) 48 | 49 | current := tpm2.AlgUnknown // 0x0000, first property 50 | caps = &Capabilities{} 51 | 52 | for { 53 | var ( 54 | data []any 55 | more bool 56 | ) 57 | 58 | data, more, err := tpm2.GetCapability(t.rwc, tpm2.CapabilityAlgs, 1, uint32(current)) 59 | if err != nil { 60 | return nil, fmt.Errorf("error getting algorithms capability: %w", err) 61 | } 62 | 63 | if d, ok := data[0].(tpm2.AlgorithmDescription); ok { 64 | alg := algorithm.Algorithm(d.ID) 65 | if !slices.Contains(caps.Algorithms, alg) { 66 | caps.Algorithms = append(caps.Algorithms, alg) 67 | } 68 | } 69 | 70 | if !more { 71 | break 72 | } 73 | 74 | current++ 75 | } 76 | 77 | t.caps = caps 78 | 79 | return 80 | } 81 | -------------------------------------------------------------------------------- /tpm/ak_test.go: -------------------------------------------------------------------------------- 1 | package tpm 2 | 3 | import ( 4 | "crypto" 5 | "crypto/x509" 6 | "encoding/base64" 7 | "encoding/json" 8 | "testing" 9 | "time" 10 | 11 | "github.com/stretchr/testify/require" 12 | "go.step.sm/crypto/keyutil" 13 | "go.step.sm/crypto/minica" 14 | "go.step.sm/crypto/x509util" 15 | ) 16 | 17 | func TestAK_MarshalJSON(t *testing.T) { 18 | ca, err := minica.New( 19 | minica.WithGetSignerFunc( 20 | func() (crypto.Signer, error) { 21 | return keyutil.GenerateSigner("RSA", "", 2048) 22 | }, 23 | ), 24 | ) 25 | require.NoError(t, err) 26 | 27 | signer, err := keyutil.GenerateSigner("RSA", "", 2048) 28 | require.NoError(t, err) 29 | 30 | cr, err := x509util.NewCertificateRequest(signer) 31 | require.NoError(t, err) 32 | cr.Subject.CommonName = "testkey" 33 | 34 | csr, err := cr.GetCertificateRequest() 35 | require.NoError(t, err) 36 | 37 | cert, err := ca.SignCSR(csr) 38 | require.NoError(t, err) 39 | 40 | ak := &AK{ 41 | name: "ak1", 42 | data: []byte{1, 2, 3, 4}, 43 | createdAt: time.Time{}, 44 | } 45 | 46 | data, err := json.Marshal(ak) 47 | require.NoError(t, err) 48 | 49 | m := map[string]any{} 50 | err = json.Unmarshal(data, &m) 51 | require.NoError(t, err) 52 | 53 | require.Equal(t, m["name"], ak.name) 54 | require.Equal(t, m["data"], base64.StdEncoding.EncodeToString(ak.data)) 55 | require.Equal(t, m["chain"], nil) 56 | require.Equal(t, m["createdAt"], ak.createdAt.Format("2006-01-02T15:04:05Z")) 57 | 58 | ak = &AK{ 59 | name: "ak2", 60 | data: []byte{1, 2, 3, 4}, 61 | chain: []*x509.Certificate{cert, ca.Intermediate}, 62 | createdAt: time.Time{}, 63 | } 64 | 65 | data, err = json.Marshal(ak) 66 | require.NoError(t, err) 67 | 68 | m = map[string]any{} 69 | err = json.Unmarshal(data, &m) 70 | require.NoError(t, err) 71 | 72 | require.Equal(t, m["name"], ak.name) 73 | require.Equal(t, m["data"], base64.StdEncoding.EncodeToString(ak.data)) 74 | require.Equal(t, m["chain"], []any{base64.StdEncoding.EncodeToString(cert.Raw), base64.StdEncoding.EncodeToString(ca.Intermediate.Raw)}) 75 | require.Equal(t, m["createdAt"], ak.createdAt.Format("2006-01-02T15:04:05Z")) 76 | } 77 | --------------------------------------------------------------------------------