Compare commits

...

52 Commits

Author SHA1 Message Date
Brandon Weeks
c5d6b1e758
Fix CodeSQL permissions take 2 (#413)
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.24.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.24.x) (push) Has been cancelled
Test / test-macos (1.24.x) (push) Has been cancelled
Test / test-windows (1.24.x) (push) Has been cancelled
2025-03-05 20:25:46 +00:00
Brandon Weeks
7d4525c388
Fix CodeSQL permissions (#412) 2025-03-05 12:06:09 -08:00
dependabot[bot]
dce70c6163
Bump the go-modules group with 3 updates (#410)
Bumps the go-modules group with 3 updates: [github.com/google/go-cmp](https://github.com/google/go-cmp), [github.com/google/go-tpm-tools](https://github.com/google/go-tpm-tools) and [golang.org/x/sys](https://github.com/golang/sys).

Updates `github.com/google/go-cmp` from 0.6.0 to 0.7.0
- [Release notes](https://github.com/google/go-cmp/releases)
- [Commits](https://github.com/google/go-cmp/compare/v0.6.0...v0.7.0)

Updates `github.com/google/go-tpm-tools` from 0.4.4 to 0.4.5
- [Release notes](https://github.com/google/go-tpm-tools/releases)
- [Changelog](https://github.com/google/go-tpm-tools/blob/main/.goreleaser.yaml)
- [Commits](https://github.com/google/go-tpm-tools/compare/v0.4.4...v0.4.5)

Updates `golang.org/x/sys` from 0.30.0 to 0.31.0
- [Commits](https://github.com/golang/sys/compare/v0.30.0...v0.31.0)

---
updated-dependencies:
- dependency-name: github.com/google/go-cmp
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: github.com/google/go-tpm-tools
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-modules
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-05 11:52:46 -08:00
Brandon Weeks
51a20034c0
Bump Go version to 1.24 (#411) 2025-03-05 11:47:52 -08:00
dependabot[bot]
a94a8af69d
Bump the github-actions group with 4 updates (#409)
Bumps the github-actions group with 4 updates: [actions/checkout](https://github.com/actions/checkout), [github/codeql-action](https://github.com/github/codeql-action), [actions/setup-go](https://github.com/actions/setup-go) and [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action).


Updates `actions/checkout` from 2 to 4
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v4)

Updates `github/codeql-action` from 1 to 3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v1...v3)

Updates `actions/setup-go` from 2 to 5
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v2...v5)

Updates `golangci/golangci-lint-action` from 3 to 6
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-05 19:29:43 +00:00
Brandon Weeks
f37925d5d0
Add github-actions to Dependabot config (#408) 2025-03-05 11:26:41 -08:00
zhsh
f7a27487f1
TPM.PCRBanks() should ignore empty PCR banks. (#406)
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
2025-02-24 08:53:28 -08:00
zhsh
d9d8fdc48e
attest: Implement discovery of supported PCR banks, rather than always blithely assuming we have exactly SHA1 and SHA256. (#404)
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
To do this, add a function to attest.TPM called PCRBanks() which enumerates the available PCR banks on a TPM. This requires plumbing through tpmBase and its implementations; the TPM1.2 implementations statically return []HashAlg{HashSHA1}, as one might expect.

To accomplish all of this, the implementation of HashAlg needed to be rethought. Now, instead of a reimplementation of tpm2.Algorithm, it's a lightweight wrapper around it. Dependent methods -- like Hash() and String() -- no longer have case HashSHA1/case HashSHA256 blocks; instead, they simply delegate to go-tpm2 for their implementations. As a result, we should never need to do something like this again.

Also add convenience constants HashSHA384 and HashSHA512.
2025-02-13 23:38:32 -08:00
dependabot[bot]
f44f5ffe7e
Bump golang.org/x/sys from 0.29.0 to 0.30.0 in the go-modules group (#403)
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
Bumps the go-modules group with 1 update: [golang.org/x/sys](https://github.com/golang/sys).


Updates `golang.org/x/sys` from 0.29.0 to 0.30.0
- [Commits](https://github.com/golang/sys/compare/v0.29.0...v0.30.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-10 09:54:13 -08:00
zhsh
9cdb0fcd55
attest: tpm.NewKeyCertifiedBy() method that does not need an entire attest.AK object. The new method only needs the AK handle and its algorithm. (#402)
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
2025-02-03 14:24:55 +11:00
zhsh
dfabc9c919
attest: Support "qualifyingData" when creating a new key. (#401) 2025-02-03 13:43:19 +11:00
Evgeny Shatokhin
c7aee80c5d attest: Support certification by ECC AKs.
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
2025-01-22 08:27:10 -08:00
Evgeny Shatokhin
1b202b12e8 attest: Support creation of ECC AK. 2025-01-22 08:27:10 -08:00
dependabot[bot]
183ad1d5ad
Bump the go-modules group across 1 directory with 2 updates (#394)
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
Bumps the go-modules group with 2 updates in the / directory: [github.com/google/go-tpm](https://github.com/google/go-tpm) and [golang.org/x/sys](https://github.com/golang/sys).


Updates `github.com/google/go-tpm` from 0.9.1 to 0.9.3
- [Release notes](https://github.com/google/go-tpm/releases)
- [Commits](https://github.com/google/go-tpm/compare/v0.9.1...v0.9.3)

Updates `golang.org/x/sys` from 0.28.0 to 0.29.0
- [Commits](https://github.com/golang/sys/compare/v0.28.0...v0.29.0)

---
updated-dependencies:
- dependency-name: github.com/google/go-tpm
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-modules
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-06 17:03:05 -08:00
dependabot[bot]
9cc576ead1
Bump golang.org/x/crypto from 0.17.0 to 0.31.0 in the go_modules group (#390)
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
Bumps the go_modules group with 1 update: [golang.org/x/crypto](https://github.com/golang/crypto).


Updates `golang.org/x/crypto` from 0.17.0 to 0.31.0
- [Commits](https://github.com/golang/crypto/compare/v0.17.0...v0.31.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-12 15:24:52 +01:00
dependabot[bot]
62f7ad0785
Bump golang.org/x/sys in the go-modules group across 1 directory (#385) 2024-11-11 07:32:39 -08:00
dependabot[bot]
f203ad3090
Bump golang.org/x/sys from 0.24.0 to 0.25.0 in the go-modules group (#383) 2024-09-09 16:25:25 +02:00
dependabot[bot]
72657612f0
Bump golang.org/x/sys from 0.23.0 to 0.24.0 in the go-modules group (#382)
Bumps the go-modules group with 1 update: [golang.org/x/sys](https://github.com/golang/sys).


Updates `golang.org/x/sys` from 0.23.0 to 0.24.0
- [Commits](https://github.com/golang/sys/compare/v0.23.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-12 09:17:08 -07:00
dependabot[bot]
ec740ef912
Bump golang.org/x/sys from 0.22.0 to 0.23.0 in the go-modules group (#381)
Bumps the go-modules group with 1 update: [golang.org/x/sys](https://github.com/golang/sys).


Updates `golang.org/x/sys` from 0.22.0 to 0.23.0
- [Commits](https://github.com/golang/sys/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 10:41:44 -04:00
dependabot[bot]
51d1c6c3c5
Bump golang.org/x/sys from 0.21.0 to 0.22.0 in the go-modules group (#378) 2024-07-08 07:56:01 -07:00
Brandon Weeks
0c084813e6
Configured Dependabot grouped updates (#376) 2024-06-10 18:00:21 +00:00
dependabot[bot]
5d68dfee1b
Bump github.com/google/go-tpm from 0.9.0 to 0.9.1 (#375)
Bumps [github.com/google/go-tpm](https://github.com/google/go-tpm) from 0.9.0 to 0.9.1.
- [Release notes](https://github.com/google/go-tpm/releases)
- [Commits](https://github.com/google/go-tpm/compare/v0.9.0...v0.9.1)

---
updated-dependencies:
- dependency-name: github.com/google/go-tpm
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-10 09:58:30 -07:00
dependabot[bot]
b7a5927d66
Bump golang.org/x/sys from 0.20.0 to 0.21.0 (#374)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.20.0 to 0.21.0.
- [Commits](https://github.com/golang/sys/compare/v0.20.0...v0.21.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-10 08:58:12 -07:00
dependabot[bot]
b36ec6af0a
Bump golang.org/x/sys from 0.19.0 to 0.20.0 (#373)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.19.0 to 0.20.0.
- [Commits](https://github.com/golang/sys/compare/v0.19.0...v0.20.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 08:34:28 -07:00
whongda
0722a4900b
Support sha384 RSA signature (#372)
Add signature algorithm details for sha384 RSA signature so certificates
using it can has its signature algorithm properly parsed
2024-04-15 15:05:48 -07:00
dependabot[bot]
545501297e
Bump golang.org/x/sys from 0.18.0 to 0.19.0 (#371)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.18.0 to 0.19.0.
- [Commits](https://github.com/golang/sys/compare/v0.18.0...v0.19.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-08 15:29:20 -04:00
dependabot[bot]
5148956a0c
Bump github.com/google/go-tpm-tools from 0.4.3 to 0.4.4 (#369)
Bumps [github.com/google/go-tpm-tools](https://github.com/google/go-tpm-tools) from 0.4.3 to 0.4.4.
- [Release notes](https://github.com/google/go-tpm-tools/releases)
- [Changelog](https://github.com/google/go-tpm-tools/blob/main/.goreleaser.yaml)
- [Commits](https://github.com/google/go-tpm-tools/compare/v0.4.3...v0.4.4)

---
updated-dependencies:
- dependency-name: github.com/google/go-tpm-tools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 08:15:39 -07:00
zhsh
a9866d34bb
A note for Linux clients of tpm.EKs(). (#368)
Fix the doc for attest.ActivateCredentialWithEK() as well.
2024-03-27 09:09:08 -07:00
Liam Murphy
5b3763098f
Add critical bool arg to MarshalSubjectAltName to allow SANs to be critical (#367) 2024-03-26 23:34:46 +00:00
dependabot[bot]
e6ab626979
Bump github.com/google/go-tpm-tools from 0.4.2 to 0.4.3 (#364)
Bumps [github.com/google/go-tpm-tools](https://github.com/google/go-tpm-tools) from 0.4.2 to 0.4.3.
- [Release notes](https://github.com/google/go-tpm-tools/releases)
- [Changelog](https://github.com/google/go-tpm-tools/blob/main/.goreleaser.yaml)
- [Commits](https://github.com/google/go-tpm-tools/compare/v0.4.2...v0.4.3)

---
updated-dependencies:
- dependency-name: github.com/google/go-tpm-tools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-26 16:55:42 +00:00
dependabot[bot]
52542411c5
Bump golang.org/x/sys from 0.16.0 to 0.18.0 (#365)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.16.0 to 0.18.0.
- [Commits](https://github.com/golang/sys/compare/v0.16.0...v0.18.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-26 09:53:17 -07:00
dependabot[bot]
02cf9e2ddd
Bump golang.org/x/sys from 0.15.0 to 0.16.0 (#360)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.15.0 to 0.16.0.
- [Commits](https://github.com/golang/sys/compare/v0.15.0...v0.16.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-08 09:25:02 -08:00
dependabot[bot]
8b301f2d45
Bump golang.org/x/crypto from 0.13.0 to 0.17.0 (#359)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.13.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.13.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-18 15:34:50 -08:00
dependabot[bot]
3d017c0234
Bump golang.org/x/sys from 0.14.0 to 0.15.0 (#358)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.14.0 to 0.15.0.
- [Commits](https://github.com/golang/sys/compare/v0.14.0...v0.15.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-04 10:58:25 -08:00
Marcin Wielgoszewski
a3545dfc94
don't drop leading zeroes when performing generic ecdsa signing (#357)
call ret.FillBytes() instead of ret.Bytes() to preserve leading zeroes that may have been dropped when converting the digest to an integer
2023-11-09 08:39:58 -08:00
dependabot[bot]
93c5899459
Bump golang.org/x/sys from 0.13.0 to 0.14.0 (#356)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.13.0 to 0.14.0.
- [Commits](https://github.com/golang/sys/compare/v0.13.0...v0.14.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-06 07:47:43 -08:00
dependabot[bot]
74a49366bd
Bump github.com/google/go-tpm-tools from 0.4.1 to 0.4.2 (#355)
Bumps [github.com/google/go-tpm-tools](https://github.com/google/go-tpm-tools) from 0.4.1 to 0.4.2.
- [Release notes](https://github.com/google/go-tpm-tools/releases)
- [Changelog](https://github.com/google/go-tpm-tools/blob/main/.goreleaser.yaml)
- [Commits](https://github.com/google/go-tpm-tools/compare/v0.4.1...v0.4.2)

---
updated-dependencies:
- dependency-name: github.com/google/go-tpm-tools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 09:14:26 -07:00
dependabot[bot]
776dc3ac22
Bump golang.org/x/sys from 0.12.0 to 0.13.0 (#353)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.12.0 to 0.13.0.
- [Commits](https://github.com/golang/sys/compare/v0.12.0...v0.13.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-16 16:58:28 +00:00
dependabot[bot]
136789e2e1
Bump github.com/google/go-cmp from 0.5.9 to 0.6.0 (#354)
Bumps [github.com/google/go-cmp](https://github.com/google/go-cmp) from 0.5.9 to 0.6.0.
- [Release notes](https://github.com/google/go-cmp/releases)
- [Commits](https://github.com/google/go-cmp/compare/v0.5.9...v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/google/go-cmp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-16 09:55:31 -07:00
dependabot[bot]
82eb5d47a2
Bump github.com/google/go-tpm-tools from 0.4.0 to 0.4.1 (#352)
Bumps [github.com/google/go-tpm-tools](https://github.com/google/go-tpm-tools) from 0.4.0 to 0.4.1.
- [Release notes](https://github.com/google/go-tpm-tools/releases)
- [Changelog](https://github.com/google/go-tpm-tools/blob/master/.goreleaser.yaml)
- [Commits](https://github.com/google/go-tpm-tools/compare/v0.4.0...v0.4.1)

---
updated-dependencies:
- dependency-name: github.com/google/go-tpm-tools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-18 08:32:24 -07:00
dependabot[bot]
f4ab877258
Bump github.com/google/go-tpm-tools (#351)
Bumps [github.com/google/go-tpm-tools](https://github.com/google/go-tpm-tools) from 0.3.13-0.20230620182252-4639ecce2aba to 0.4.0.
- [Release notes](https://github.com/google/go-tpm-tools/releases)
- [Changelog](https://github.com/google/go-tpm-tools/blob/master/.goreleaser.yaml)
- [Commits](https://github.com/google/go-tpm-tools/commits/v0.4.0)

---
updated-dependencies:
- dependency-name: github.com/google/go-tpm-tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-11 08:03:38 -07:00
Herman Slatman
3d71f101b1
Fix Intel EK certificate URLs on Linux (#347) 2023-09-08 18:23:49 +00:00
Damien Miller
42c11fc152
Fix typo (#349) 2023-09-08 17:46:44 +00:00
dependabot[bot]
3c84bff65e
Bump golang.org/x/sys from 0.9.0 to 0.12.0 (#348)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.9.0 to 0.12.0.
- [Commits](https://github.com/golang/sys/compare/v0.9.0...v0.12.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-08 17:42:41 +00:00
Brandon Weeks
ab5dee2ae5
ci: don't install OpenSSL 1.1 on macOS (#350)
GitHub actions runner macos-13 version 20230801.2 appears to include
this by default, causing a link failure.

da18545f2f
2023-09-08 10:33:41 -07:00
zhsh
046550658b
attest: Create keys under non-default SRKs (#342) 2023-07-11 10:14:13 -04:00
zhsh
310e2caafe
attest: Remove the EK field from AK struct (#341) 2023-06-29 07:53:53 -07:00
zhsh
60adf13bc0
attest: ActivateCredentialWithEK() method that can be used with non-default EKs. (#340) 2023-06-28 20:38:36 -07:00
zhsh
a56e8c4896
Activate AK with ECC EKs. (#339) 2023-06-27 20:02:47 -07:00
smo4201
8af5f4e7de
attest: Make PCRs included in quote configurable (#311)
Change the low-level Quote() functions so that the PCRs to be
included in the quote is selectable. Does not change the
high-level attestPlatform functions, which still retrieve
all PCRs.
2023-06-26 23:04:59 +00:00
zhsh
b92d1c69bf
Add TPM.EKCertificates() method, it returns all certificates from TPM's NVRAM (#333) 2023-06-23 15:10:34 -07:00
zhsh
d29df30553
Add EK as a field to AK struct. (#332)
The change is a no-op for existing clients, and it will simplify
adding the support for ECC EKs. The activation code no longer makes
assumptions about EK's type and handle (i.e. RSA and 0x81010001),
and instead relies on TPM.EKs() to provide the EK's details.
2023-06-22 13:17:47 -07:00
25 changed files with 958 additions and 268 deletions

View File

@ -4,3 +4,16 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: "weekly" interval: "weekly"
groups:
"Go modules":
patterns:
- "*"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
groups:
github-actions:
patterns:
- "*"

View File

@ -1,5 +1,9 @@
name: "CodeQL" name: "CodeQL"
permissions:
contents: read
security-events: write
on: on:
push: push:
branches: [master] branches: [master]
@ -20,7 +24,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
fetch-depth: 2 fetch-depth: 2
@ -28,12 +32,12 @@ jobs:
if: ${{ github.event_name == 'pull_request' }} if: ${{ github.event_name == 'pull_request' }}
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v1 uses: github/codeql-action/init@v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v1 uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1 uses: github/codeql-action/analyze@v3

View File

@ -8,11 +8,11 @@ jobs:
name: lint name: lint
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/setup-go@v3 - uses: actions/setup-go@v5
with: with:
go-version: 1.20.x go-version: 1.24.x
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v3 uses: golangci/golangci-lint-action@v6
with: with:
version: v1.53.3 version: v1.64.6

View File

@ -13,29 +13,29 @@ jobs:
test-linux: test-linux:
strategy: strategy:
matrix: matrix:
go-version: [1.20.x] go-version: [1.24.x]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Install Go - name: Install Go
uses: actions/setup-go@v2 uses: actions/setup-go@v5
with: with:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Test - name: Test
run: go test ./... run: go test ./...
test-linux-tpm12: test-linux-tpm12:
strategy: strategy:
matrix: matrix:
go-version: [1.20.x] go-version: [1.24.x]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Install Go - name: Install Go
uses: actions/setup-go@v2 uses: actions/setup-go@v5
with: with:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install libtspi - name: Install libtspi
run: sudo apt-get install -y libtspi-dev run: sudo apt-get install -y libtspi-dev
- name: Test - name: Test
@ -43,33 +43,29 @@ jobs:
test-macos: test-macos:
strategy: strategy:
matrix: matrix:
go-version: [1.20.x] go-version: [1.24.x]
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- name: Install Go - name: Install Go
uses: actions/setup-go@v2 uses: actions/setup-go@v5
with: with:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v4
# See https://github.com/google/go-tpm-tools#macos-dev # See https://github.com/google/go-tpm-tools#macos-dev
- name: Install openssl
run: brew install openssl@1.1
- name: Link openssl
run: sudo ln -s $(brew --prefix openssl@1.1)/include/openssl /usr/local/include
- name: Test - name: Test
run: C_INCLUDE_PATH="$(brew --prefix openssl@1.1)/include" LIBRARY_PATH="$(brew --prefix openssl@1.1)/lib" go test ./... run: C_INCLUDE_PATH="$(brew --prefix openssl@1.1)/include" LIBRARY_PATH="$(brew --prefix openssl@1.1)/lib" go test ./...
test-windows: test-windows:
strategy: strategy:
matrix: matrix:
go-version: [1.20.x] go-version: [1.24.x]
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- name: Install Go - name: Install Go
uses: actions/setup-go@v2 uses: actions/setup-go@v5
with: with:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Test - name: Test
run: go build ./... run: go build ./...

View File

@ -72,6 +72,14 @@ type KeyConfig struct {
// Size is used to specify the bit size of the key or elliptic curve. For // Size is used to specify the bit size of the key or elliptic curve. For
// example, '256' is used to specify curve P-256. // example, '256' is used to specify curve P-256.
Size int Size int
// Parent describes the Storage Root Key that will be used as a parent.
// If nil, the default SRK (i.e. RSA with handle 0x81000001) is assumed.
// Supported only by TPM 2.0 on Linux.
Parent *ParentKeyConfig
// QualifyingData is an optional data that will be included into
// a TPM-generated signature of the minted key.
// It may contain any data chosen by the caller.
QualifyingData []byte
} }
// defaultConfig is used when no other configuration is specified. // defaultConfig is used when no other configuration is specified.

View File

@ -100,6 +100,22 @@ func testKeyCreateAndLoad(t *testing.T, tpm *TPM) {
Size: 2048, Size: 2048,
}, },
}, },
{
name: "QualifyingData-RSA",
opts: &KeyConfig{
Algorithm: RSA,
Size: 2048,
QualifyingData: []byte("qualifying data"),
},
},
{
name: "QualifyingData-ECDSA",
opts: &KeyConfig{
Algorithm: ECDSA,
Size: 256,
QualifyingData: []byte("qualifying data"),
},
},
} { } {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
sk, err := tpm.NewKey(ak, test.opts) sk, err := tpm.NewKey(ak, test.opts)

View File

@ -140,7 +140,7 @@ func runCommand(tpm *attest.TPM) error {
fmt.Printf("Version: %d\n", info.Version) fmt.Printf("Version: %d\n", info.Version)
fmt.Printf("Interface: %d\n", info.Interface) fmt.Printf("Interface: %d\n", info.Interface)
fmt.Printf("VendorInfo: %x\n", info.VendorInfo) fmt.Printf("VendorInfo: %x\n", info.VendorInfo)
fmt.Printf("Manufactorer: %v\n", info.Manufacturer) fmt.Printf("Manufacturer: %v\n", info.Manufacturer)
case "make-ak", "make-aik": case "make-ak", "make-aik":
k, err := tpm.NewAK(nil) k, err := tpm.NewAK(nil)

View File

@ -25,6 +25,7 @@ import (
"github.com/google/go-tpm/legacy/tpm2" "github.com/google/go-tpm/legacy/tpm2"
"github.com/google/go-tpm/tpm" "github.com/google/go-tpm/tpm"
"github.com/google/go-tpm/tpmutil"
) )
// TPMVersion is used to configure a preference in // TPMVersion is used to configure a preference in
@ -98,13 +99,25 @@ const (
keyEncodingParameterized keyEncodingParameterized
) )
// ParentKeyConfig describes the Storage Root Key that is used
// as a parent for new keys.
type ParentKeyConfig struct {
Algorithm Algorithm
Handle tpmutil.Handle
}
var defaultParentConfig = ParentKeyConfig{
Algorithm: RSA,
Handle: 0x81000001,
}
type ak interface { type ak interface {
close(tpmBase) error close(tpmBase) error
marshal() ([]byte, error) marshal() ([]byte, error)
activateCredential(tpm tpmBase, in EncryptedCredential) ([]byte, error) activateCredential(tpm tpmBase, in EncryptedCredential, ek *EK) ([]byte, error)
quote(t tpmBase, nonce []byte, alg HashAlg) (*Quote, error) quote(t tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error)
attestationParameters() AttestationParameters attestationParameters() AttestationParameters
certify(tb tpmBase, handle interface{}) (*CertificationParameters, error) certify(tb tpmBase, handle interface{}, opts CertifyOpts) (*CertificationParameters, error)
} }
// AK represents a key which can be used for attestation. // AK represents a key which can be used for attestation.
@ -126,11 +139,22 @@ func (k *AK) Marshal() ([]byte, error) {
} }
// ActivateCredential decrypts the secret using the key to prove that the AK // ActivateCredential decrypts the secret using the key to prove that the AK
// was generated on the same TPM as the EK. // was generated on the same TPM as the EK. This method can be used with TPMs
// that have the default EK, i.e. RSA EK with handle 0x81010001.
// //
// This operation is synonymous with TPM2_ActivateCredential. // This operation is synonymous with TPM2_ActivateCredential.
func (k *AK) ActivateCredential(tpm *TPM, in EncryptedCredential) (secret []byte, err error) { func (k *AK) ActivateCredential(tpm *TPM, in EncryptedCredential) (secret []byte, err error) {
return k.ak.activateCredential(tpm.tpm, in) return k.ak.activateCredential(tpm.tpm, in, nil)
}
// ActivateCredentialWithEK decrypts the secret using the key to prove that the AK
// was generated on the same TPM as the EK. This method can be used with TPMs
// that have an ECC EK. The 'ek' argument must be one of EKs returned from
// TPM.EKs() or TPM.EKCertificates().
//
// This operation is synonymous with TPM2_ActivateCredential.
func (k *AK) ActivateCredentialWithEK(tpm *TPM, in EncryptedCredential, ek EK) (secret []byte, err error) {
return k.ak.activateCredential(tpm.tpm, in, &ek)
} }
// Quote returns a quote over the platform state, signed by the AK. // Quote returns a quote over the platform state, signed by the AK.
@ -138,7 +162,16 @@ func (k *AK) ActivateCredential(tpm *TPM, in EncryptedCredential) (secret []byte
// This is a low-level API. Consumers seeking to attest the state of the // This is a low-level API. Consumers seeking to attest the state of the
// platform should use tpm.AttestPlatform() instead. // platform should use tpm.AttestPlatform() instead.
func (k *AK) Quote(tpm *TPM, nonce []byte, alg HashAlg) (*Quote, error) { func (k *AK) Quote(tpm *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
return k.ak.quote(tpm.tpm, nonce, alg) pcrs := make([]int, 24)
for pcr := range pcrs {
pcrs[pcr] = pcr
}
return k.ak.quote(tpm.tpm, nonce, alg, pcrs)
}
// QuotePCRs is like Quote() but allows the caller to select a subset of the PCRs.
func (k *AK) QuotePCRs(tpm *TPM, nonce []byte, alg HashAlg, pcrs []int) (*Quote, error) {
return k.ak.quote(tpm.tpm, nonce, alg, pcrs)
} }
// AttestationParameters returns information about the AK, typically used to // AttestationParameters returns information about the AK, typically used to
@ -152,12 +185,18 @@ func (k *AK) AttestationParameters() AttestationParameters {
// key. Depending on the actual instantiation it can accept different handle // key. Depending on the actual instantiation it can accept different handle
// types (e.g., tpmutil.Handle on Linux or uintptr on Windows). // types (e.g., tpmutil.Handle on Linux or uintptr on Windows).
func (k *AK) Certify(tpm *TPM, handle interface{}) (*CertificationParameters, error) { func (k *AK) Certify(tpm *TPM, handle interface{}) (*CertificationParameters, error) {
return k.ak.certify(tpm.tpm, handle) return k.ak.certify(tpm.tpm, handle, CertifyOpts{})
} }
// AKConfig encapsulates parameters for minting keys. This type is defined // AKConfig encapsulates parameters for minting keys.
// now (despite being empty) for future interface compatibility.
type AKConfig struct { type AKConfig struct {
// Parent describes the Storage Root Key that will be used as a parent.
// If nil, the default SRK (i.e. RSA with handle 0x81000001) is assumed.
// Supported only by TPM 2.0 on Linux.
Parent *ParentKeyConfig
// If not specified, the default algorithm (RSA) is assumed.
Algorithm Algorithm
} }
// EncryptedCredential represents encrypted parameters which must be activated // EncryptedCredential represents encrypted parameters which must be activated
@ -205,6 +244,9 @@ type EK struct {
// Public key. Clients or servers can perform an HTTP GET to this URL, and // Public key. Clients or servers can perform an HTTP GET to this URL, and
// use ParseEKCertificate on the response body. // use ParseEKCertificate on the response body.
CertificateURL string CertificateURL string
// The EK persistent handle.
handle tpmutil.Handle
} }
// AttestationParameters describes information about a key which is necessary // AttestationParameters describes information about a key which is necessary
@ -357,41 +399,30 @@ func (a *AKPublic) VerifyAll(quotes []Quote, pcrs []PCR, nonce []byte) error {
// HashAlg identifies a hashing Algorithm. // HashAlg identifies a hashing Algorithm.
type HashAlg uint8 type HashAlg uint8
// Valid hash algorithms. // Known valid hash algorithms.
var ( var (
HashSHA1 = HashAlg(tpm2.AlgSHA1) HashSHA1 = HashAlg(tpm2.AlgSHA1)
HashSHA256 = HashAlg(tpm2.AlgSHA256) HashSHA256 = HashAlg(tpm2.AlgSHA256)
HashSHA384 = HashAlg(tpm2.AlgSHA384)
HashSHA512 = HashAlg(tpm2.AlgSHA512)
) )
func (a HashAlg) cryptoHash() crypto.Hash { func (a HashAlg) cryptoHash() crypto.Hash {
switch a { g := a.goTPMAlg()
case HashSHA1: h, err := g.Hash()
return crypto.SHA1 if err != nil {
case HashSHA256: panic(fmt.Sprintf("HashAlg %v (corresponding to TPM2.Algorithm %v) has no corresponding crypto.Hash", a, g))
return crypto.SHA256
} }
return 0 return h
} }
func (a HashAlg) goTPMAlg() tpm2.Algorithm { func (a HashAlg) goTPMAlg() tpm2.Algorithm {
switch a { return tpm2.Algorithm(a)
case HashSHA1:
return tpm2.AlgSHA1
case HashSHA256:
return tpm2.AlgSHA256
}
return 0
} }
// String returns a human-friendly representation of the hash algorithm. // String returns a human-friendly representation of the hash algorithm.
func (a HashAlg) String() string { func (a HashAlg) String() string {
switch a { return a.goTPMAlg().String()
case HashSHA1:
return "SHA1"
case HashSHA256:
return "SHA256"
}
return fmt.Sprintf("HashAlg<%d>", int(a))
} }
// PlatformParameters encapsulates the set of information necessary to attest // PlatformParameters encapsulates the set of information necessary to attest

View File

@ -67,8 +67,29 @@ func TestSimTPM20Info(t *testing.T) {
func TestSimTPM20AKCreateAndLoad(t *testing.T) { func TestSimTPM20AKCreateAndLoad(t *testing.T) {
sim, tpm := setupSimulatedTPM(t) sim, tpm := setupSimulatedTPM(t)
defer sim.Close() defer sim.Close()
for _, test := range []struct {
ak, err := tpm.NewAK(nil) name string
opts *AKConfig
}{
{
name: "NoConfig",
opts: nil,
},
{
name: "EmptyConfig",
opts: &AKConfig{},
},
{
name: "RSA",
opts: &AKConfig{Algorithm: RSA},
},
{
name: "ECDSA",
opts: &AKConfig{Algorithm: ECDSA},
},
} {
t.Run(test.name, func(t *testing.T) {
ak, err := tpm.NewAK(test.opts)
if err != nil { if err != nil {
t.Fatalf("NewAK() failed: %v", err) t.Fatalf("NewAK() failed: %v", err)
} }
@ -84,7 +105,7 @@ func TestSimTPM20AKCreateAndLoad(t *testing.T) {
loaded, err := tpm.LoadAK(enc) loaded, err := tpm.LoadAK(enc)
if err != nil { if err != nil {
t.Fatalf("LoadKey() failed: %v", err) t.Fatalf("LoadAK() failed: %v", err)
} }
defer loaded.Close(tpm) defer loaded.Close(tpm)
@ -95,35 +116,50 @@ func TestSimTPM20AKCreateAndLoad(t *testing.T) {
t.Logf("Original = %v", k1.public) t.Logf("Original = %v", k1.public)
t.Logf("Loaded = %v", k2.public) t.Logf("Loaded = %v", k2.public)
} }
})
}
} }
func TestSimTPM20ActivateCredential(t *testing.T) { func TestSimTPM20ActivateCredential(t *testing.T) {
testActivateCredential(t, false)
}
func TestSimTPM20ActivateCredentialWithEK(t *testing.T) {
testActivateCredential(t, true)
}
func testActivateCredential(t *testing.T, useEK bool) {
sim, tpm := setupSimulatedTPM(t) sim, tpm := setupSimulatedTPM(t)
defer sim.Close() defer sim.Close()
ak, err := tpm.NewAK(nil)
if err != nil {
t.Fatalf("NewAK() failed: %v", err)
}
defer ak.Close(tpm)
EKs, err := tpm.EKs() EKs, err := tpm.EKs()
if err != nil { if err != nil {
t.Fatalf("EKs() failed: %v", err) t.Fatalf("EKs() failed: %v", err)
} }
ek := chooseEK(t, EKs) ek := chooseEK(t, EKs)
ak, err := tpm.NewAK(nil)
if err != nil {
t.Fatalf("NewAK() failed: %v", err)
}
defer ak.Close(tpm)
ap := ActivationParameters{ ap := ActivationParameters{
TPMVersion: TPMVersion20, TPMVersion: TPMVersion20,
AK: ak.AttestationParameters(), AK: ak.AttestationParameters(),
EK: ek, EK: ek.Public,
} }
secret, challenge, err := ap.Generate() secret, challenge, err := ap.Generate()
if err != nil { if err != nil {
t.Fatalf("Generate() failed: %v", err) t.Fatalf("Generate() failed: %v", err)
} }
decryptedSecret, err := ak.ActivateCredential(tpm, *challenge) var decryptedSecret []byte
if useEK {
decryptedSecret, err = ak.ActivateCredentialWithEK(tpm, *challenge, ek)
} else {
decryptedSecret, err = ak.ActivateCredential(tpm, *challenge)
}
if err != nil { if err != nil {
t.Errorf("ak.ActivateCredential() failed: %v", err) t.Errorf("ak.ActivateCredential() failed: %v", err)
} }
@ -246,24 +282,69 @@ func TestSimTPM20PCRs(t *testing.T) {
} }
} }
func TestSimTPM20Persistence(t *testing.T) { func TestSimTPM20PersistenceSRK(t *testing.T) {
testPersistenceSRK(t, defaultParentConfig)
}
func TestSimTPM20PersistenceECCSRK(t *testing.T) {
parentConfig := ParentKeyConfig{
Algorithm: ECDSA,
Handle: 0x81000002,
}
testPersistenceSRK(t, parentConfig)
}
func testPersistenceSRK(t *testing.T, parentConfig ParentKeyConfig) {
sim, tpm := setupSimulatedTPM(t) sim, tpm := setupSimulatedTPM(t)
defer sim.Close() defer sim.Close()
ekHnd, _, err := tpm.tpm.(*wrappedTPM20).getPrimaryKeyHandle(commonRSAEkEquivalentHandle) srkHnd, _, err := tpm.tpm.(*wrappedTPM20).getStorageRootKeyHandle(parentConfig)
if err != nil { if err != nil {
t.Fatalf("getPrimaryKeyHandle() failed: %v", err) t.Fatalf("getStorageRootKeyHandle() failed: %v", err)
} }
if ekHnd != commonRSAEkEquivalentHandle { if srkHnd != parentConfig.Handle {
t.Fatalf("bad EK-equivalent handle: got 0x%x, wanted 0x%x", ekHnd, commonRSAEkEquivalentHandle) t.Fatalf("bad SRK-equivalent handle: got 0x%x, wanted 0x%x", srkHnd, parentConfig.Handle)
} }
ekHnd, p, err := tpm.tpm.(*wrappedTPM20).getPrimaryKeyHandle(commonRSAEkEquivalentHandle) srkHnd, p, err := tpm.tpm.(*wrappedTPM20).getStorageRootKeyHandle(parentConfig)
if err != nil { if err != nil {
t.Fatalf("second getPrimaryKeyHandle() failed: %v", err) t.Fatalf("second getStorageRootKeyHandle() failed: %v", err)
} }
if ekHnd != commonRSAEkEquivalentHandle { if srkHnd != parentConfig.Handle {
t.Fatalf("bad EK-equivalent handle: got 0x%x, wanted 0x%x", ekHnd, commonRSAEkEquivalentHandle) t.Fatalf("bad SRK-equivalent handle: got 0x%x, wanted 0x%x", srkHnd, parentConfig.Handle)
}
if p {
t.Fatalf("generated a new key the second time; that shouldn't happen")
}
}
func TestSimTPM20PersistenceEK(t *testing.T) {
sim, tpm := setupSimulatedTPM(t)
defer sim.Close()
eks, err := tpm.EKs()
if err != nil {
t.Errorf("EKs() failed: %v", err)
}
if len(eks) == 0 || (eks[0].Public == nil) {
t.Errorf("EKs() = %v, want at least 1 EK with populated fields", eks)
}
ek := eks[0]
ekHnd, _, err := tpm.tpm.(*wrappedTPM20).getEndorsementKeyHandle(&ek)
if err != nil {
t.Fatalf("getStorageRootKeyHandle() failed: %v", err)
}
if ekHnd != ek.handle {
t.Fatalf("bad EK-equivalent handle: got 0x%x, wanted 0x%x", ekHnd, ek.handle)
}
ekHnd, p, err := tpm.tpm.(*wrappedTPM20).getEndorsementKeyHandle(&ek)
if err != nil {
t.Fatalf("second getEndorsementKeyHandle() failed: %v", err)
}
if ekHnd != ek.handle {
t.Fatalf("bad EK-equivalent handle: got 0x%x, wanted 0x%x", ekHnd, ek.handle)
} }
if p { if p {
t.Fatalf("generated a new key the second time; that shouldn't happen") t.Fatalf("generated a new key the second time; that shouldn't happen")

View File

@ -16,7 +16,6 @@ package attest
import ( import (
"bytes" "bytes"
"crypto"
"flag" "flag"
"fmt" "fmt"
"reflect" "reflect"
@ -84,13 +83,35 @@ func TestAKCreateAndLoad(t *testing.T) {
if !*testLocal { if !*testLocal {
t.SkipNow() t.SkipNow()
} }
for _, test := range []struct {
name string
opts *AKConfig
}{
{
name: "NoConfig",
opts: nil,
},
{
name: "EmptyConfig",
opts: &AKConfig{},
},
{
name: "RSA",
opts: &AKConfig{Algorithm: RSA},
},
{
name: "ECDSA",
opts: &AKConfig{Algorithm: ECDSA},
},
} {
t.Run(test.name, func(t *testing.T) {
tpm, err := OpenTPM(nil) tpm, err := OpenTPM(nil)
if err != nil { if err != nil {
t.Fatalf("OpenTPM() failed: %v", err) t.Fatalf("OpenTPM() failed: %v", err)
} }
defer tpm.Close() defer tpm.Close()
ak, err := tpm.NewAK(nil) ak, err := tpm.NewAK(test.opts)
if err != nil { if err != nil {
t.Fatalf("NewAK() failed: %v", err) t.Fatalf("NewAK() failed: %v", err)
} }
@ -106,7 +127,7 @@ func TestAKCreateAndLoad(t *testing.T) {
loaded, err := tpm.LoadAK(enc) loaded, err := tpm.LoadAK(enc)
if err != nil { if err != nil {
t.Fatalf("LoadKey() failed: %v", err) t.Fatalf("LoadAK() failed: %v", err)
} }
defer loaded.Close(tpm) defer loaded.Close(tpm)
@ -117,18 +138,20 @@ func TestAKCreateAndLoad(t *testing.T) {
t.Logf("Original = %v", k1.public) t.Logf("Original = %v", k1.public)
t.Logf("Loaded = %v", k2.public) t.Logf("Loaded = %v", k2.public)
} }
})
}
} }
// chooseEK selects the EK public which will be activated against. // chooseEK selects the EK which will be activated against.
func chooseEK(t *testing.T, eks []EK) crypto.PublicKey { func chooseEK(t *testing.T, eks []EK) EK {
t.Helper() t.Helper()
for _, ek := range eks { for _, ek := range eks {
return ek.Public return ek
} }
t.Fatalf("No suitable EK found") t.Fatalf("No suitable EK found")
return nil return EK{}
} }
func TestPCRs(t *testing.T) { func TestPCRs(t *testing.T) {

View File

@ -151,7 +151,7 @@ func TestTPMActivateCredential(t *testing.T) {
ap := ActivationParameters{ ap := ActivationParameters{
TPMVersion: TPMVersion12, TPMVersion: TPMVersion12,
AK: ak.AttestationParameters(), AK: ak.AttestationParameters(),
EK: ek, EK: ek.Public,
} }
secret, challenge, err := ap.Generate() secret, challenge, err := ap.Generate()
if err != nil { if err != nil {

View File

@ -17,6 +17,7 @@ package attest
import ( import (
"bytes" "bytes"
"crypto" "crypto"
"crypto/ecdsa"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"errors" "errors"
@ -82,6 +83,12 @@ type ActivateOpts struct {
VerifierKeyNameDigest *tpm2.HashValue VerifierKeyNameDigest *tpm2.HashValue
} }
// CertifyOpts specifies options for the key's certification.
type CertifyOpts struct {
// QualifyingData is the user provided qualifying data.
QualifyingData []byte
}
// NewActivateOpts creates options for use in generating an activation challenge for a certified key. // NewActivateOpts creates options for use in generating an activation challenge for a certified key.
// The computed hash is the name digest of the public key used to verify the certification of our key. // The computed hash is the name digest of the public key used to verify the certification of our key.
func NewActivateOpts(verifierPubKey tpm2.Public, ek crypto.PublicKey) (*ActivateOpts, error) { func NewActivateOpts(verifierPubKey tpm2.Public, ek crypto.PublicKey) (*ActivateOpts, error) {
@ -164,11 +171,6 @@ func (p *CertificationParameters) Verify(opts VerifyOpts) error {
} }
// Check the signature over the attestation data verifies correctly. // Check the signature over the attestation data verifies correctly.
// TODO: Support ECC certifying keys
pk, ok := opts.Public.(*rsa.PublicKey)
if !ok {
return fmt.Errorf("only RSA verification keys are supported")
}
if !opts.Hash.Available() { if !opts.Hash.Available() {
return fmt.Errorf("hash function is unavailable") return fmt.Errorf("hash function is unavailable")
} }
@ -184,9 +186,18 @@ func (p *CertificationParameters) Verify(opts VerifyOpts) error {
return fmt.Errorf("DecodeSignature() failed: %v", err) return fmt.Errorf("DecodeSignature() failed: %v", err)
} }
switch pk := opts.Public.(type) {
case *rsa.PublicKey:
if err := rsa.VerifyPKCS1v15(pk, opts.Hash, hsh.Sum(nil), sig.RSA.Signature); err != nil { if err := rsa.VerifyPKCS1v15(pk, opts.Hash, hsh.Sum(nil), sig.RSA.Signature); err != nil {
return fmt.Errorf("could not verify attestation: %v", err) return fmt.Errorf("could not verify attestation: %v", err)
} }
case *ecdsa.PublicKey:
if ok := ecdsa.Verify(pk, hsh.Sum(nil), sig.ECC.R, sig.ECC.S); !ok {
return fmt.Errorf("could not verify ECC attestation")
}
default:
return fmt.Errorf("unsupported public key type: %T", pub)
}
return nil return nil
} }
@ -236,9 +247,9 @@ func (p *CertificationParameters) Generate(rnd io.Reader, verifyOpts VerifyOpts,
}, nil }, nil
} }
// certify uses AK's handle and the passed signature scheme to certify the key // certify uses AK's handle, the passed user qualifying data, and the passed
// with the `hnd` handle. // signature scheme to certify the key with the `hnd` handle.
func certify(tpm io.ReadWriteCloser, hnd, akHnd tpmutil.Handle, scheme tpm2.SigScheme) (*CertificationParameters, error) { func certify(tpm io.ReadWriteCloser, hnd, akHnd tpmutil.Handle, qualifyingData []byte, scheme tpm2.SigScheme) (*CertificationParameters, error) {
pub, _, _, err := tpm2.ReadPublic(tpm, hnd) pub, _, _, err := tpm2.ReadPublic(tpm, hnd)
if err != nil { if err != nil {
return nil, fmt.Errorf("tpm2.ReadPublic() failed: %v", err) return nil, fmt.Errorf("tpm2.ReadPublic() failed: %v", err)
@ -247,7 +258,7 @@ func certify(tpm io.ReadWriteCloser, hnd, akHnd tpmutil.Handle, scheme tpm2.SigS
if err != nil { if err != nil {
return nil, fmt.Errorf("could not encode public key: %v", err) return nil, fmt.Errorf("could not encode public key: %v", err)
} }
att, sig, err := tpm2.CertifyEx(tpm, "", "", hnd, akHnd, nil, scheme) att, sig, err := tpm2.CertifyEx(tpm, "", "", hnd, akHnd, qualifyingData, scheme)
if err != nil { if err != nil {
return nil, fmt.Errorf("tpm2.Certify() failed: %v", err) return nil, fmt.Errorf("tpm2.Certify() failed: %v", err)
} }

View File

@ -24,6 +24,7 @@ import (
"crypto" "crypto"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"slices"
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
@ -31,13 +32,19 @@ import (
"github.com/google/go-tpm/legacy/tpm2" "github.com/google/go-tpm/legacy/tpm2"
) )
func TestSimTPM20CertificationParameters(t *testing.T) { func TestSimTPM20CertificationParametersRSA(t *testing.T) {
sim, tpm := setupSimulatedTPM(t) sim, tpm := setupSimulatedTPM(t)
defer sim.Close() defer sim.Close()
testCertificationParameters(t, tpm) testCertificationParameters(t, tpm, RSA)
} }
func TestTPM20CertificationParameters(t *testing.T) { func TestSimTPM20CertificationParametersECC(t *testing.T) {
sim, tpm := setupSimulatedTPM(t)
defer sim.Close()
testCertificationParameters(t, tpm, ECDSA)
}
func TestTPM20CertificationParametersRSA(t *testing.T) {
if !*testLocal { if !*testLocal {
t.SkipNow() t.SkipNow()
} }
@ -46,11 +53,23 @@ func TestTPM20CertificationParameters(t *testing.T) {
t.Fatalf("OpenTPM() failed: %v", err) t.Fatalf("OpenTPM() failed: %v", err)
} }
defer tpm.Close() defer tpm.Close()
testCertificationParameters(t, tpm) testCertificationParameters(t, tpm, RSA)
} }
func testCertificationParameters(t *testing.T, tpm *TPM) { func TestTPM20CertificationParametersECC(t *testing.T) {
ak, err := tpm.NewAK(nil) if !*testLocal {
t.SkipNow()
}
tpm, err := OpenTPM(nil)
if err != nil {
t.Fatalf("OpenTPM() failed: %v", err)
}
defer tpm.Close()
testCertificationParameters(t, tpm, ECDSA)
}
func testCertificationParameters(t *testing.T, tpm *TPM, akAlg Algorithm) {
ak, err := tpm.NewAK(&AKConfig{Algorithm: akAlg})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -59,12 +78,12 @@ func testCertificationParameters(t *testing.T, tpm *TPM) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if pub.Type != tpm2.AlgRSA {
t.Fatal("non-RSA verifying key")
}
pk := &rsa.PublicKey{E: int(pub.RSAParameters.Exponent()), N: pub.RSAParameters.Modulus()} pk, err := pub.Key()
hash, err := pub.RSAParameters.Sign.Hash.Hash() if err != nil {
t.Fatal(err)
}
hash, err := pub.NameAlg.Hash()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -170,13 +189,19 @@ func testCertificationParameters(t *testing.T, tpm *TPM) {
} }
} }
func TestSimTPM20KeyCertification(t *testing.T) { func TestSimTPM20KeyCertificationRSA(t *testing.T) {
sim, tpm := setupSimulatedTPM(t) sim, tpm := setupSimulatedTPM(t)
defer sim.Close() defer sim.Close()
testKeyCertification(t, tpm) testKeyCertification(t, tpm, RSA)
} }
func TestTPM20KeyCertification(t *testing.T) { func TestSimTPM20KeyCertificationECC(t *testing.T) {
sim, tpm := setupSimulatedTPM(t)
defer sim.Close()
testKeyCertification(t, tpm, ECDSA)
}
func TestTPM20KeyCertificationRSA(t *testing.T) {
if !*testLocal { if !*testLocal {
t.SkipNow() t.SkipNow()
} }
@ -185,11 +210,32 @@ func TestTPM20KeyCertification(t *testing.T) {
t.Fatalf("OpenTPM() failed: %v", err) t.Fatalf("OpenTPM() failed: %v", err)
} }
defer tpm.Close() defer tpm.Close()
testKeyCertification(t, tpm) testKeyCertification(t, tpm, RSA)
} }
func testKeyCertification(t *testing.T, tpm *TPM) { func TestTPM20KeyCertificationECC(t *testing.T) {
ak, err := tpm.NewAK(nil) if !*testLocal {
t.SkipNow()
}
tpm, err := OpenTPM(nil)
if err != nil {
t.Fatalf("OpenTPM() failed: %v", err)
}
defer tpm.Close()
testKeyCertification(t, tpm, ECDSA)
}
func extraData(t *testing.T, p CertificationParameters) []byte {
t.Helper()
ad, err := tpm2.DecodeAttestationData(p.CreateAttestation)
if err != nil {
t.Fatalf("failed to decode attestation data: %v", err)
}
return ad.ExtraData
}
func testKeyCertification(t *testing.T, tpm *TPM, akAlg Algorithm) {
ak, err := tpm.NewAK(&AKConfig{Algorithm: akAlg})
if err != nil { if err != nil {
t.Fatalf("NewAK() failed: %v", err) t.Fatalf("NewAK() failed: %v", err)
} }
@ -198,8 +244,11 @@ func testKeyCertification(t *testing.T, tpm *TPM) {
if err != nil { if err != nil {
t.Fatalf("DecodePublic() failed: %v", err) t.Fatalf("DecodePublic() failed: %v", err)
} }
pk := &rsa.PublicKey{E: int(pub.RSAParameters.Exponent()), N: pub.RSAParameters.Modulus()} pk, err := pub.Key()
hash, err := pub.RSAParameters.Sign.Hash.Hash() if err != nil {
t.Fatalf("pub.Key() failed: %v", err)
}
hash, err := pub.NameAlg.Hash()
if err != nil { if err != nil {
t.Fatalf("cannot access AK's hash function: %v", err) t.Fatalf("cannot access AK's hash function: %v", err)
} }
@ -210,6 +259,7 @@ func testKeyCertification(t *testing.T, tpm *TPM) {
for _, test := range []struct { for _, test := range []struct {
name string name string
opts *KeyConfig opts *KeyConfig
wantExtraData []byte
err error err error
}{ }{
{ {
@ -257,6 +307,26 @@ func testKeyCertification(t *testing.T, tpm *TPM) {
}, },
err: nil, err: nil,
}, },
{
name: "QualifyingData-RSA",
opts: &KeyConfig{
Algorithm: RSA,
Size: 2048,
QualifyingData: []byte("qualifying data"),
},
wantExtraData: []byte("qualifying data"),
err: nil,
},
{
name: "QualifyingData-ECDSA",
opts: &KeyConfig{
Algorithm: ECDSA,
Size: 384,
QualifyingData: []byte("qualifying data"),
},
wantExtraData: []byte("qualifying data"),
err: nil,
},
} { } {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
sk, err := tpm.NewKey(ak, test.opts) sk, err := tpm.NewKey(ak, test.opts)
@ -265,6 +335,9 @@ func testKeyCertification(t *testing.T, tpm *TPM) {
} }
defer sk.Close() defer sk.Close()
p := sk.CertificationParameters() p := sk.CertificationParameters()
if gotExtraData, wantExtraData := extraData(t, p), test.wantExtraData; !slices.Equal(gotExtraData, wantExtraData) {
t.Errorf("ExtraData got = %v, want = %v", gotExtraData, wantExtraData)
}
err = p.Verify(verifyOpts) err = p.Verify(verifyOpts)
if test.err == nil && err == nil { if test.err == nil && err == nil {
return return

View File

@ -533,15 +533,7 @@ func ParseEventLog(measurementLog []byte) (*EventLog, error) {
return nil, fmt.Errorf("failed to parse spec ID event: %v", err) return nil, fmt.Errorf("failed to parse spec ID event: %v", err)
} }
for _, alg := range specID.algs { for _, alg := range specID.algs {
switch tpm2.Algorithm(alg.ID) { el.Algs = append(el.Algs, HashAlg(alg.ID))
case tpm2.AlgSHA1:
el.Algs = append(el.Algs, HashSHA1)
case tpm2.AlgSHA256:
el.Algs = append(el.Algs, HashSHA256)
}
}
if len(el.Algs) == 0 {
return nil, fmt.Errorf("measurement log didn't use sha1 or sha256 digests")
} }
// Switch to parsing crypto agile events. Don't include this in the // Switch to parsing crypto agile events. Don't include this in the
// replayed events since it intentionally doesn't extend the PCRs. // replayed events since it intentionally doesn't extend the PCRs.

View File

@ -91,12 +91,62 @@ func ExampleAK_credentialActivation() {
} }
} }
func ExampleAK_credentialActivationWithEK() {
tpm, err := attest.OpenTPM(nil)
if err != nil {
log.Fatalf("Failed to open TPM: %v", err)
}
defer tpm.Close()
// Create a new AK.
ak, err := tpm.NewAK(nil)
if err != nil {
log.Fatalf("Failed to create AK: %v", err)
}
defer ak.Close(tpm)
// Read the EK certificates.
ekCerts, err := tpm.EKCertificates()
if err != nil {
log.Fatalf("Failed to enumerate EKs: %v", err)
}
// Read parameters necessary to generate a challenge.
ap := ak.AttestationParameters()
// Try activating with each EK certificate.
for _, ek := range ekCerts {
// Generate a credential activation challenge (usually done on the server).
activation := attest.ActivationParameters{
TPMVersion: tpm.Version(),
EK: ek.Public,
AK: ap,
}
secret, challenge, err := activation.Generate()
if err != nil {
log.Fatalf("Failed to generate activation challenge: %v", err)
}
// Challenge the AK & EK properties to recieve the decrypted secret.
decrypted, err := ak.ActivateCredentialWithEK(tpm, *challenge, ek)
if err != nil {
log.Fatalf("Failed to activate credential: %v", err)
}
// Check that the AK completed the challenge (usually done on the server).
if subtle.ConstantTimeCompare(secret, decrypted) == 0 {
log.Fatal("Activation response did not match secret")
}
}
}
func TestExampleAK(t *testing.T) { func TestExampleAK(t *testing.T) {
if !*testExamples { if !*testExamples {
t.SkipNow() t.SkipNow()
} }
ExampleAK() ExampleAK()
ExampleAK_credentialActivation() ExampleAK_credentialActivation()
ExampleAK_credentialActivationWithEK()
} }
func TestExampleTPM(t *testing.T) { func TestExampleTPM(t *testing.T) {

View File

@ -52,7 +52,7 @@ func (k *trousersKey12) close(tpm tpmBase) error {
return nil // No state for tpm 1.2. return nil // No state for tpm 1.2.
} }
func (k *trousersKey12) activateCredential(tb tpmBase, in EncryptedCredential) ([]byte, error) { func (k *trousersKey12) activateCredential(tb tpmBase, in EncryptedCredential, ek *EK) ([]byte, error) {
t, ok := tb.(*trousersTPM) t, ok := tb.(*trousersTPM)
if !ok { if !ok {
return nil, fmt.Errorf("expected *linuxTPM, got %T", tb) return nil, fmt.Errorf("expected *linuxTPM, got %T", tb)
@ -65,7 +65,7 @@ func (k *trousersKey12) activateCredential(tb tpmBase, in EncryptedCredential) (
return cred, nil return cred, nil
} }
func (k *trousersKey12) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, error) { func (k *trousersKey12) quote(tb tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error) {
t, ok := tb.(*trousersTPM) t, ok := tb.(*trousersTPM)
if !ok { if !ok {
return nil, fmt.Errorf("expected *linuxTPM, got %T", tb) return nil, fmt.Errorf("expected *linuxTPM, got %T", tb)
@ -73,6 +73,9 @@ func (k *trousersKey12) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, er
if alg != HashSHA1 { if alg != HashSHA1 {
return nil, fmt.Errorf("only SHA1 algorithms supported on TPM 1.2, not %v", alg) return nil, fmt.Errorf("only SHA1 algorithms supported on TPM 1.2, not %v", alg)
} }
if selectedPCRs != nil {
return nil, fmt.Errorf("selecting PCRs not supported on TPM 1.2 (parameter must be nil)")
}
quote, rawSig, err := attestation.GetQuote(t.ctx, k.blob, nonce) quote, rawSig, err := attestation.GetQuote(t.ctx, k.blob, nonce)
if err != nil { if err != nil {
@ -93,6 +96,6 @@ func (k *trousersKey12) attestationParameters() AttestationParameters {
} }
} }
func (k *trousersKey12) certify(tb tpmBase, handle interface{}) (*CertificationParameters, error) { func (k *trousersKey12) certify(tb tpmBase, handle interface{}, _ CertifyOpts) (*CertificationParameters, error) {
return nil, fmt.Errorf("not implemented") return nil, fmt.Errorf("not implemented")
} }

View File

@ -49,7 +49,7 @@ func (k *windowsKey12) marshal() ([]byte, error) {
return out.Serialize() return out.Serialize()
} }
func (k *windowsKey12) activateCredential(t tpmBase, in EncryptedCredential) ([]byte, error) { func (k *windowsKey12) activateCredential(t tpmBase, in EncryptedCredential, ek *EK) ([]byte, error) {
tpm, ok := t.(*windowsTPM) tpm, ok := t.(*windowsTPM)
if !ok { if !ok {
return nil, fmt.Errorf("expected *windowsTPM, got %T", t) return nil, fmt.Errorf("expected *windowsTPM, got %T", t)
@ -61,7 +61,7 @@ func (k *windowsKey12) activateCredential(t tpmBase, in EncryptedCredential) ([]
return decryptCredential(secretKey, in.Secret) return decryptCredential(secretKey, in.Secret)
} }
func (k *windowsKey12) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, error) { func (k *windowsKey12) quote(tb tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error) {
if alg != HashSHA1 { if alg != HashSHA1 {
return nil, fmt.Errorf("only SHA1 algorithms supported on TPM 1.2, not %v", alg) return nil, fmt.Errorf("only SHA1 algorithms supported on TPM 1.2, not %v", alg)
} }
@ -80,11 +80,6 @@ func (k *windowsKey12) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, err
return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err) return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err)
} }
selectedPCRs := make([]int, 24)
for pcr := range selectedPCRs {
selectedPCRs[pcr] = pcr
}
sig, pcrc, err := tpm1.Quote(tpm, tpmKeyHnd, nonce, selectedPCRs[:], wellKnownAuth[:]) sig, pcrc, err := tpm1.Quote(tpm, tpmKeyHnd, nonce, selectedPCRs[:], wellKnownAuth[:])
if err != nil { if err != nil {
return nil, fmt.Errorf("Quote() failed: %v", err) return nil, fmt.Errorf("Quote() failed: %v", err)
@ -112,7 +107,7 @@ func (k *windowsKey12) attestationParameters() AttestationParameters {
Public: k.public, Public: k.public,
} }
} }
func (k *windowsKey12) certify(tb tpmBase, handle interface{}) (*CertificationParameters, error) { func (k *windowsKey12) certify(tb tpmBase, handle interface{}, _ CertifyOpts) (*CertificationParameters, error) {
return nil, fmt.Errorf("not implemented") return nil, fmt.Errorf("not implemented")
} }
@ -152,7 +147,7 @@ func (k *windowsKey20) marshal() ([]byte, error) {
return out.Serialize() return out.Serialize()
} }
func (k *windowsKey20) activateCredential(t tpmBase, in EncryptedCredential) ([]byte, error) { func (k *windowsKey20) activateCredential(t tpmBase, in EncryptedCredential, ek *EK) ([]byte, error) {
tpm, ok := t.(*windowsTPM) tpm, ok := t.(*windowsTPM)
if !ok { if !ok {
return nil, fmt.Errorf("expected *windowsTPM, got %T", t) return nil, fmt.Errorf("expected *windowsTPM, got %T", t)
@ -160,7 +155,7 @@ func (k *windowsKey20) activateCredential(t tpmBase, in EncryptedCredential) ([]
return tpm.pcp.ActivateCredential(k.hnd, append(in.Credential, in.Secret...)) return tpm.pcp.ActivateCredential(k.hnd, append(in.Credential, in.Secret...))
} }
func (k *windowsKey20) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, error) { func (k *windowsKey20) quote(tb tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error) {
t, ok := tb.(*windowsTPM) t, ok := tb.(*windowsTPM)
if !ok { if !ok {
return nil, fmt.Errorf("expected *windowsTPM, got %T", tb) return nil, fmt.Errorf("expected *windowsTPM, got %T", tb)
@ -174,7 +169,7 @@ func (k *windowsKey20) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, err
if err != nil { if err != nil {
return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err) return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err)
} }
return quote20(tpm, tpmKeyHnd, alg.goTPMAlg(), nonce) return quote20(tpm, tpmKeyHnd, alg.goTPMAlg(), nonce, selectedPCRs)
} }
func (k *windowsKey20) close(tpm tpmBase) error { func (k *windowsKey20) close(tpm tpmBase) error {
@ -190,7 +185,7 @@ func (k *windowsKey20) attestationParameters() AttestationParameters {
} }
} }
func (k *windowsKey20) certify(tb tpmBase, handle interface{}) (*CertificationParameters, error) { func (k *windowsKey20) certify(tb tpmBase, handle interface{}, _ CertifyOpts) (*CertificationParameters, error) {
t, ok := tb.(*windowsTPM) t, ok := tb.(*windowsTPM)
if !ok { if !ok {
return nil, fmt.Errorf("expected *windowsTPM, got %T", tb) return nil, fmt.Errorf("expected *windowsTPM, got %T", tb)
@ -215,5 +210,5 @@ func (k *windowsKey20) certify(tb tpmBase, handle interface{}) (*CertificationPa
Alg: tpm2.AlgRSASSA, Alg: tpm2.AlgRSASSA,
Hash: tpm2.AlgSHA1, // PCP-created AK uses SHA1 Hash: tpm2.AlgSHA1, // PCP-created AK uses SHA1
} }
return certify(tpm, hnd, akHnd, scheme) return certify(tpm, hnd, akHnd, nil, scheme)
} }

View File

@ -29,6 +29,7 @@ import (
"github.com/google/go-tpm/legacy/tpm2" "github.com/google/go-tpm/legacy/tpm2"
"github.com/google/go-tpm/tpmutil" "github.com/google/go-tpm/tpmutil"
"go.uber.org/multierr"
) )
const ( const (
@ -39,14 +40,16 @@ const (
// Defined in "Registry of reserved TPM 2.0 handles and localities". // Defined in "Registry of reserved TPM 2.0 handles and localities".
nvramRSACertIndex = 0x1c00002 nvramRSACertIndex = 0x1c00002
nvramRSAEkNonceIndex = 0x1c00003 nvramRSAEkNonceIndex = 0x1c00003
nvramECCCertIndex = 0x1c0000a
nvramECCEkNonceIndex = 0x1c0000b
// Defined in "Registry of reserved TPM 2.0 handles and localities", and checked on a glinux machine. // Defined in "Registry of reserved TPM 2.0 handles and localities", and checked on a glinux machine.
commonSrkEquivalentHandle = 0x81000001
commonRSAEkEquivalentHandle = 0x81010001 commonRSAEkEquivalentHandle = 0x81010001
commonECCEkEquivalentHandle = 0x81010002
) )
var ( var (
akTemplate = tpm2.Public{ akTemplateRSA = tpm2.Public{
Type: tpm2.AlgRSA, Type: tpm2.AlgRSA,
NameAlg: tpm2.AlgSHA256, NameAlg: tpm2.AlgSHA256,
Attributes: tpm2.FlagSignerDefault | tpm2.FlagNoDA, Attributes: tpm2.FlagSignerDefault | tpm2.FlagNoDA,
@ -58,7 +61,23 @@ var (
KeyBits: 2048, KeyBits: 2048,
}, },
} }
defaultSRKTemplate = tpm2.Public{ akTemplateECC = tpm2.Public{
Type: tpm2.AlgECC,
NameAlg: tpm2.AlgSHA256,
Attributes: tpm2.FlagSignerDefault | tpm2.FlagNoDA,
ECCParameters: &tpm2.ECCParams{
Sign: &tpm2.SigScheme{
Alg: tpm2.AlgECDSA,
Hash: tpm2.AlgSHA256,
},
CurveID: tpm2.CurveNISTP256,
Point: tpm2.ECPoint{
XRaw: make([]byte, 32),
YRaw: make([]byte, 32),
},
},
}
defaultRSASRKTemplate = tpm2.Public{
Type: tpm2.AlgRSA, Type: tpm2.AlgRSA,
NameAlg: tpm2.AlgSHA256, NameAlg: tpm2.AlgSHA256,
Attributes: tpm2.FlagStorageDefault | tpm2.FlagNoDA, Attributes: tpm2.FlagStorageDefault | tpm2.FlagNoDA,
@ -72,7 +91,24 @@ var (
KeyBits: 2048, KeyBits: 2048,
}, },
} }
// Default RSA EK template defined in: defaultECCSRKTemplate = tpm2.Public{
Type: tpm2.AlgECC,
NameAlg: tpm2.AlgSHA256,
Attributes: tpm2.FlagStorageDefault | tpm2.FlagNoDA,
ECCParameters: &tpm2.ECCParams{
Symmetric: &tpm2.SymScheme{
Alg: tpm2.AlgAES,
KeyBits: 128,
Mode: tpm2.AlgCFB,
},
CurveID: tpm2.CurveNISTP256,
Point: tpm2.ECPoint{
XRaw: make([]byte, 32),
YRaw: make([]byte, 32),
},
},
}
// Default RSA and ECC EK templates defined in:
// https://trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf // https://trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf
defaultRSAEKTemplate = tpm2.Public{ defaultRSAEKTemplate = tpm2.Public{
Type: tpm2.AlgRSA, Type: tpm2.AlgRSA,
@ -97,6 +133,32 @@ var (
ModulusRaw: make([]byte, 256), ModulusRaw: make([]byte, 256),
}, },
} }
defaultECCEKTemplate = tpm2.Public{
Type: tpm2.AlgECC,
NameAlg: tpm2.AlgSHA256,
Attributes: tpm2.FlagFixedTPM | tpm2.FlagFixedParent | tpm2.FlagSensitiveDataOrigin |
tpm2.FlagAdminWithPolicy | tpm2.FlagRestricted | tpm2.FlagDecrypt,
AuthPolicy: []byte{
0x83, 0x71, 0x97, 0x67, 0x44, 0x84,
0xB3, 0xF8, 0x1A, 0x90, 0xCC, 0x8D,
0x46, 0xA5, 0xD7, 0x24, 0xFD, 0x52,
0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64,
0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14,
0x69, 0xAA,
},
ECCParameters: &tpm2.ECCParams{
Symmetric: &tpm2.SymScheme{
Alg: tpm2.AlgAES,
KeyBits: 128,
Mode: tpm2.AlgCFB,
},
CurveID: tpm2.CurveNISTP256,
Point: tpm2.ECPoint{
XRaw: make([]byte, 32),
YRaw: make([]byte, 32),
},
},
}
// Basic template for an ECDSA key signing outside-TPM objects. Other // Basic template for an ECDSA key signing outside-TPM objects. Other
// fields are populated depending on the key creation options. // fields are populated depending on the key creation options.
ecdsaKeyTemplate = tpm2.Public{ ecdsaKeyTemplate = tpm2.Public{
@ -234,12 +296,9 @@ func readEKCertFromNVRAM20(tpm io.ReadWriter, nvramCertIndex tpmutil.Handle) (*x
return ParseEKCertificate(ekCert) return ParseEKCertificate(ekCert)
} }
func quote20(tpm io.ReadWriter, akHandle tpmutil.Handle, hashAlg tpm2.Algorithm, nonce []byte) (*Quote, error) { func quote20(tpm io.ReadWriter, akHandle tpmutil.Handle, hashAlg tpm2.Algorithm, nonce []byte, selectedPCRs []int) (*Quote, error) {
sel := tpm2.PCRSelection{Hash: hashAlg} sel := tpm2.PCRSelection{Hash: hashAlg,
numPCRs := 24 PCRs: selectedPCRs}
for pcr := 0; pcr < numPCRs; pcr++ {
sel.PCRs = append(sel.PCRs, pcr)
}
quote, sig, err := tpm2.Quote(tpm, akHandle, "", "", nonce, sel, tpm2.AlgNull) quote, sig, err := tpm2.Quote(tpm, akHandle, "", "", nonce, sel, tpm2.AlgNull)
if err != nil { if err != nil {
@ -254,6 +313,31 @@ func quote20(tpm io.ReadWriter, akHandle tpmutil.Handle, hashAlg tpm2.Algorithm,
}, err }, err
} }
func pcrbanks(tpm io.ReadWriter) ([]HashAlg, error) {
vals, _, err := tpm2.GetCapability(tpm, tpm2.CapabilityPCRs, 1024, 0)
if err != nil {
return nil, fmt.Errorf("failed to get TPM available PCR banks: %w", err)
}
var hAlgs []HashAlg
var errs error
for i, v := range vals {
pcrb, ok := v.(tpm2.PCRSelection)
if !ok {
errs = multierr.Append(errs, fmt.Errorf("failed to convert value %d to tpm2.PCRSelection: %v", i, v))
continue
}
if len(pcrb.PCRs) == 0 {
// ignore empty PCR banks.
continue
}
hAlgs = append(hAlgs, HashAlg(pcrb.Hash))
}
return hAlgs, errs
}
func readAllPCRs20(tpm io.ReadWriter, alg tpm2.Algorithm) (map[uint32][]byte, error) { func readAllPCRs20(tpm io.ReadWriter, alg tpm2.Algorithm) (map[uint32][]byte, error) {
numPCRs := 24 numPCRs := 24
out := map[uint32][]byte{} out := map[uint32][]byte{}
@ -297,12 +381,17 @@ type tpmBase interface {
close() error close() error
tpmVersion() TPMVersion tpmVersion() TPMVersion
eks() ([]EK, error) eks() ([]EK, error)
ekCertificates() ([]EK, error)
info() (*TPMInfo, error) info() (*TPMInfo, error)
pcrbanks() ([]HashAlg, error)
loadAK(opaqueBlob []byte) (*AK, error) loadAK(opaqueBlob []byte) (*AK, error)
loadAKWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*AK, error)
newAK(opts *AKConfig) (*AK, error) newAK(opts *AKConfig) (*AK, error)
loadKey(opaqueBlob []byte) (*Key, error) loadKey(opaqueBlob []byte) (*Key, error)
loadKeyWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*Key, error)
newKey(ak *AK, opts *KeyConfig) (*Key, error) newKey(ak *AK, opts *KeyConfig) (*Key, error)
newKeyCertifiedByKey(ck certifyingKey, opts *KeyConfig) (*Key, error)
pcrs(alg HashAlg) ([]PCR, error) pcrs(alg HashAlg) ([]PCR, error)
measurementLog() ([]byte, error) measurementLog() ([]byte, error)
} }
@ -320,10 +409,20 @@ func (t *TPM) Close() error {
} }
// EKs returns the endorsement keys burned-in to the platform. // EKs returns the endorsement keys burned-in to the platform.
// Note for Linux clients: for historical reasons, the method assumes that
// the TPM has a single EK, and the EK's type is RSA. If the EK's type is ECC
// and the TPM contains an ECC EK Certificate, the EKCertificates() method
// should be used to retrieve the EKs.
func (t *TPM) EKs() ([]EK, error) { func (t *TPM) EKs() ([]EK, error) {
return t.tpm.eks() return t.tpm.eks()
} }
// EKCertificates returns the endorsement key certificates burned-in to the platform.
// It is guaranteed that each EK.Certificate field will be populated.
func (t *TPM) EKCertificates() ([]EK, error) {
return t.tpm.ekCertificates()
}
// Info returns information about the TPM. // Info returns information about the TPM.
func (t *TPM) Info() (*TPMInfo, error) { func (t *TPM) Info() (*TPMInfo, error) {
return t.tpm.info() return t.tpm.info()
@ -337,6 +436,12 @@ func (t *TPM) LoadAK(opaqueBlob []byte) (*AK, error) {
return t.tpm.loadAK(opaqueBlob) return t.tpm.loadAK(opaqueBlob)
} }
// LoadAKWithParent loads a previously-created ak into the TPM
// under the given parent for use.
func (t *TPM) LoadAKWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*AK, error) {
return t.tpm.loadAKWithParent(opaqueBlob, parent)
}
// MeasurementLog returns the present value of the System Measurement Log. // MeasurementLog returns the present value of the System Measurement Log.
// //
// This is a low-level API. Consumers seeking to attest the state of the // This is a low-level API. Consumers seeking to attest the state of the
@ -372,6 +477,22 @@ func (t *TPM) NewKey(ak *AK, opts *KeyConfig) (*Key, error) {
return t.tpm.newKey(ak, opts) return t.tpm.newKey(ak, opts)
} }
// NewKeyCertifiedByKey creates an application key certified by
// the attestation key. Unlike NewKey(), this method does not require
// an attest.AK object and only requires the AK handle and its algorithm.
// Thus it can be used in cases where the attestation key was not created
// by go-attestation library. If opts is nil then DefaultConfig is used.
func (t *TPM) NewKeyCertifiedByKey(akHandle tpmutil.Handle, akAlg Algorithm, opts *KeyConfig) (*Key, error) {
if opts == nil {
opts = defaultConfig
}
if opts.Algorithm == "" && opts.Size == 0 {
opts = defaultConfig
}
ck := certifyingKey{handle: akHandle, alg: akAlg}
return t.tpm.newKeyCertifiedByKey(ck, opts)
}
// LoadKey loads a previously-created application key into the TPM for use. // LoadKey loads a previously-created application key into the TPM for use.
// A key loaded via this function needs to be closed with .Close(). // A key loaded via this function needs to be closed with .Close().
// Only blobs generated by calling Key.Marshal() are valid parameters // Only blobs generated by calling Key.Marshal() are valid parameters
@ -389,11 +510,20 @@ func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
return t.tpm.pcrs(alg) return t.tpm.pcrs(alg)
} }
// PCRBanks returns the list of supported PCR banks on the TPM.
//
// This is a low-level API. Consumers seeking to attest the state of the
// platform should use tpm.AttestPlatform() instead.
func (t *TPM) PCRBanks() ([]HashAlg, error) {
return t.tpm.pcrbanks()
}
func (t *TPM) attestPCRs(ak *AK, nonce []byte, alg HashAlg) (*Quote, []PCR, error) { func (t *TPM) attestPCRs(ak *AK, nonce []byte, alg HashAlg) (*Quote, []PCR, error) {
pcrs, err := t.PCRs(alg) pcrs, err := t.PCRs(alg)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to read %v PCRs: %v", alg, err) return nil, nil, fmt.Errorf("failed to read %v PCRs: %v", alg, err)
} }
quote, err := ak.Quote(t, nonce, alg) quote, err := ak.Quote(t, nonce, alg)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to quote using %v: %v", alg, err) return nil, nil, fmt.Errorf("failed to quote using %v: %v", alg, err)
@ -419,9 +549,9 @@ func (t *TPM) attestPlatform(ak *AK, nonce []byte, eventLog []byte) (*PlatformPa
EventLog: eventLog, EventLog: eventLog,
} }
algs := []HashAlg{HashSHA1} algs, err := t.PCRBanks()
if t.Version() == TPMVersion20 { if err != nil {
algs = []HashAlg{HashSHA1, HashSHA256} return nil, fmt.Errorf("failed to get PCR banks: %w", err)
} }
var lastErr error var lastErr error

View File

@ -94,7 +94,7 @@ func readEKCertFromNVRAM12(ctx *tspi.Context) (*x509.Certificate, error) {
return ParseEKCertificate(ekCert) return ParseEKCertificate(ekCert)
} }
func (t *trousersTPM) eks() ([]EK, error) { func (t *trousersTPM) ekCertificates() ([]EK, error) {
cert, err := readEKCertFromNVRAM12(t.ctx) cert, err := readEKCertFromNVRAM12(t.ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("readEKCertFromNVRAM failed: %v", err) return nil, fmt.Errorf("readEKCertFromNVRAM failed: %v", err)
@ -104,14 +104,26 @@ func (t *trousersTPM) eks() ([]EK, error) {
}, nil }, nil
} }
func (t *trousersTPM) eks() ([]EK, error) {
return t.ekCertificates()
}
func (t *trousersTPM) newKey(*AK, *KeyConfig) (*Key, error) { func (t *trousersTPM) newKey(*AK, *KeyConfig) (*Key, error) {
return nil, fmt.Errorf("not implemented") return nil, fmt.Errorf("not implemented")
} }
func (t *trousersTPM) newKeyCertifiedByKey(ck certifyingKey, opts *KeyConfig) (*Key, error) {
return nil, fmt.Errorf("not implemented")
}
func (t *trousersTPM) loadKey(opaqueBlob []byte) (*Key, error) { func (t *trousersTPM) loadKey(opaqueBlob []byte) (*Key, error) {
return nil, fmt.Errorf("not implemented") return nil, fmt.Errorf("not implemented")
} }
func (t *trousersTPM) loadKeyWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*Key, error) {
return nil, fmt.Errorf("not implemented")
}
func (t *trousersTPM) newAK(opts *AKConfig) (*AK, error) { func (t *trousersTPM) newAK(opts *AKConfig) (*AK, error) {
pub, blob, err := attestation.CreateAIK(t.ctx) pub, blob, err := attestation.CreateAIK(t.ctx)
if err != nil { if err != nil {
@ -132,6 +144,10 @@ func (t *trousersTPM) loadAK(opaqueBlob []byte) (*AK, error) {
return &AK{ak: newTrousersKey12(sKey.Blob, sKey.Public)}, nil return &AK{ak: newTrousersKey12(sKey.Blob, sKey.Public)}, nil
} }
func (t *trousersTPM) loadAKWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*AK, error) {
return nil, fmt.Errorf("not implemented")
}
// allPCRs12 returns a map of all the PCR values on the TPM // allPCRs12 returns a map of all the PCR values on the TPM
func allPCRs12(ctx *tspi.Context) (map[uint32][]byte, error) { func allPCRs12(ctx *tspi.Context) (map[uint32][]byte, error) {
tpm := ctx.GetTPM() tpm := ctx.GetTPM()
@ -147,6 +163,10 @@ func allPCRs12(ctx *tspi.Context) (map[uint32][]byte, error) {
return PCRs, nil return PCRs, nil
} }
func (t *trousersTPM) pcrbanks() ([]HashAlg, error) {
return []HashAlg{HashSHA1}, nil
}
func (t *trousersTPM) pcrs(alg HashAlg) ([]PCR, error) { func (t *trousersTPM) pcrs(alg HashAlg) ([]PCR, error) {
if alg != HashSHA1 { if alg != HashSHA1 {
return nil, fmt.Errorf("non-SHA1 algorithm %v is not supported on TPM 1.2", alg) return nil, fmt.Errorf("non-SHA1 algorithm %v is not supported on TPM 1.2", alg)

View File

@ -152,6 +152,18 @@ func (t *windowsTPM) info() (*TPMInfo, error) {
return &tInfo, nil return &tInfo, nil
} }
func (t *windowsTPM) ekCertificates() ([]EK, error) {
ekCerts, err := t.pcp.EKCerts()
if err != nil {
return nil, fmt.Errorf("could not read EKCerts: %v", err)
}
var eks []EK
for _, cert := range ekCerts {
eks = append(eks, EK{Certificate: cert, Public: cert.PublicKey})
}
return eks, nil
}
func (t *windowsTPM) eks() ([]EK, error) { func (t *windowsTPM) eks() ([]EK, error) {
ekCerts, err := t.pcp.EKCerts() ekCerts, err := t.pcp.EKCerts()
if err != nil { if err != nil {
@ -325,14 +337,26 @@ func (t *windowsTPM) loadAK(opaqueBlob []byte) (*AK, error) {
} }
} }
func (t *windowsTPM) loadAKWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*AK, error) {
return nil, fmt.Errorf("not implemented")
}
func (t *windowsTPM) newKey(*AK, *KeyConfig) (*Key, error) { func (t *windowsTPM) newKey(*AK, *KeyConfig) (*Key, error) {
return nil, fmt.Errorf("not implemented") return nil, fmt.Errorf("not implemented")
} }
func (t *windowsTPM) newKeyCertifiedByKey(ck certifyingKey, opts *KeyConfig) (*Key, error) {
return nil, fmt.Errorf("not implemented")
}
func (t *windowsTPM) loadKey(opaqueBlob []byte) (*Key, error) { func (t *windowsTPM) loadKey(opaqueBlob []byte) (*Key, error) {
return nil, fmt.Errorf("not implemented") return nil, fmt.Errorf("not implemented")
} }
func (t *windowsTPM) loadKeyWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*Key, error) {
return nil, fmt.Errorf("not implemented")
}
func allPCRs12(tpm io.ReadWriter) (map[uint32][]byte, error) { func allPCRs12(tpm io.ReadWriter) (map[uint32][]byte, error) {
numPCRs := 24 numPCRs := 24
out := map[uint32][]byte{} out := map[uint32][]byte{}
@ -352,6 +376,23 @@ func allPCRs12(tpm io.ReadWriter) (map[uint32][]byte, error) {
return out, nil return out, nil
} }
func (t *windowsTPM) pcrbanks() ([]HashAlg, error) {
switch t.version {
case TPMVersion12:
return []HashAlg{HashSHA1}, nil
case TPMVersion20:
tpm, err := t.pcp.TPMCommandInterface()
if err != nil {
return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err)
}
return pcrbanks(tpm)
default:
return nil, fmt.Errorf("unsupported TPM version: %x", t.version)
}
}
func (t *windowsTPM) pcrs(alg HashAlg) ([]PCR, error) { func (t *windowsTPM) pcrs(alg HashAlg) ([]PCR, error) {
var PCRs map[uint32][]byte var PCRs map[uint32][]byte

View File

@ -35,6 +35,13 @@ type wrappedTPM20 struct {
interf TPMInterface interf TPMInterface
rwc CommandChannelTPM20 rwc CommandChannelTPM20
tpmRSAEkTemplate *tpm2.Public tpmRSAEkTemplate *tpm2.Public
tpmECCEkTemplate *tpm2.Public
}
// certifyingKey contains details of a TPM key that could certify other keys.
type certifyingKey struct {
handle tpmutil.Handle
alg Algorithm
} }
func (t *wrappedTPM20) rsaEkTemplate() tpm2.Public { func (t *wrappedTPM20) rsaEkTemplate() tpm2.Public {
@ -54,6 +61,23 @@ func (t *wrappedTPM20) rsaEkTemplate() tpm2.Public {
return *t.tpmRSAEkTemplate return *t.tpmRSAEkTemplate
} }
func (t *wrappedTPM20) eccEkTemplate() tpm2.Public {
if t.tpmECCEkTemplate != nil {
return *t.tpmECCEkTemplate
}
nonce, err := tpm2.NVReadEx(t.rwc, nvramECCEkNonceIndex, tpm2.HandleOwner, "", 0)
if err != nil {
t.tpmECCEkTemplate = &defaultECCEKTemplate // No nonce, use the default template
} else {
template := defaultECCEKTemplate
copy(template.ECCParameters.Point.XRaw, nonce)
t.tpmECCEkTemplate = &template
}
return *t.tpmECCEkTemplate
}
func (t *wrappedTPM20) tpmVersion() TPMVersion { func (t *wrappedTPM20) tpmVersion() TPMVersion {
return TPMVersion20 return TPMVersion20
} }
@ -83,39 +107,100 @@ func (t *wrappedTPM20) info() (*TPMInfo, error) {
return &tInfo, nil return &tInfo, nil
} }
// Return value: handle, whether we generated a new one, error // Return value: handle, whether we generated a new one, error.
func (t *wrappedTPM20) getPrimaryKeyHandle(pHnd tpmutil.Handle) (tpmutil.Handle, bool, error) { func (t *wrappedTPM20) getEndorsementKeyHandle(ek *EK) (tpmutil.Handle, bool, error) {
_, _, _, err := tpm2.ReadPublic(t.rwc, pHnd) var ekHandle tpmutil.Handle
var ekTemplate tpm2.Public
if ek == nil {
// The default is RSA for backward compatibility.
ekHandle = commonRSAEkEquivalentHandle
ekTemplate = t.rsaEkTemplate()
} else {
ekHandle = ek.handle
if ekHandle == 0 {
// Assume RSA EK handle if it was not provided.
ekHandle = commonRSAEkEquivalentHandle
}
switch pub := ek.Public.(type) {
case *rsa.PublicKey:
ekTemplate = t.rsaEkTemplate()
case *ecdsa.PublicKey:
ekTemplate = t.eccEkTemplate()
default:
return 0, false, fmt.Errorf("unsupported public key type %T", pub)
}
}
_, _, _, err := tpm2.ReadPublic(t.rwc, ekHandle)
if err == nil { if err == nil {
// Found the persistent handle, assume it's the key we want. // Found the persistent handle, assume it's the key we want.
return pHnd, false, nil return ekHandle, false, nil
} }
rerr := err // Preserve this failure for later logging, if needed rerr := err // Preserve this failure for later logging, if needed
var keyHnd tpmutil.Handle keyHnd, _, err := tpm2.CreatePrimary(t.rwc, tpm2.HandleEndorsement, tpm2.PCRSelection{}, "", "", ekTemplate)
switch pHnd {
case commonSrkEquivalentHandle:
keyHnd, _, err = tpm2.CreatePrimary(t.rwc, tpm2.HandleOwner, tpm2.PCRSelection{}, "", "", defaultSRKTemplate)
case commonRSAEkEquivalentHandle:
keyHnd, _, err = tpm2.CreatePrimary(t.rwc, tpm2.HandleEndorsement, tpm2.PCRSelection{}, "", "", t.rsaEkTemplate())
}
if err != nil { if err != nil {
return 0, false, fmt.Errorf("ReadPublic failed (%v), and then CreatePrimary failed: %v", rerr, err) return 0, false, fmt.Errorf("ReadPublic failed (%v), and then CreatePrimary failed: %v", rerr, err)
} }
defer tpm2.FlushContext(t.rwc, keyHnd) defer tpm2.FlushContext(t.rwc, keyHnd)
err = tpm2.EvictControl(t.rwc, "", tpm2.HandleOwner, keyHnd, pHnd) err = tpm2.EvictControl(t.rwc, "", tpm2.HandleOwner, keyHnd, ekHandle)
if err != nil { if err != nil {
return 0, false, fmt.Errorf("EvictControl failed: %v", err) return 0, false, fmt.Errorf("EvictControl failed: %v", err)
} }
return pHnd, true, nil return ekHandle, true, nil
}
// Return value: handle, whether we generated a new one, error
func (t *wrappedTPM20) getStorageRootKeyHandle(parent ParentKeyConfig) (tpmutil.Handle, bool, error) {
srkHandle := parent.Handle
_, _, _, err := tpm2.ReadPublic(t.rwc, srkHandle)
if err == nil {
// Found the persistent handle, assume it's the key we want.
return srkHandle, false, nil
}
rerr := err // Preserve this failure for later logging, if needed
var srkTemplate tpm2.Public
switch parent.Algorithm {
case RSA:
srkTemplate = defaultRSASRKTemplate
case ECDSA:
srkTemplate = defaultECCSRKTemplate
default:
return 0, false, fmt.Errorf("unsupported SRK algorithm: %v", parent.Algorithm)
}
keyHnd, _, err := tpm2.CreatePrimary(t.rwc, tpm2.HandleOwner, tpm2.PCRSelection{}, "", "", srkTemplate)
if err != nil {
return 0, false, fmt.Errorf("ReadPublic failed (%v), and then CreatePrimary failed: %v", rerr, err)
}
defer tpm2.FlushContext(t.rwc, keyHnd)
err = tpm2.EvictControl(t.rwc, "", tpm2.HandleOwner, keyHnd, srkHandle)
if err != nil {
return 0, false, fmt.Errorf("EvictControl failed: %v", err)
}
return srkHandle, true, nil
}
func (t *wrappedTPM20) ekCertificates() ([]EK, error) {
var res []EK
if rsaCert, err := readEKCertFromNVRAM20(t.rwc, nvramRSACertIndex); err == nil {
res = append(res, EK{Public: crypto.PublicKey(rsaCert.PublicKey), Certificate: rsaCert, handle: commonRSAEkEquivalentHandle})
}
if eccCert, err := readEKCertFromNVRAM20(t.rwc, nvramECCCertIndex); err == nil {
res = append(res, EK{Public: crypto.PublicKey(eccCert.PublicKey), Certificate: eccCert, handle: commonECCEkEquivalentHandle})
}
return res, nil
} }
func (t *wrappedTPM20) eks() ([]EK, error) { func (t *wrappedTPM20) eks() ([]EK, error) {
if cert, err := readEKCertFromNVRAM20(t.rwc, nvramRSACertIndex); err == nil { if cert, err := readEKCertFromNVRAM20(t.rwc, nvramRSACertIndex); err == nil {
return []EK{ return []EK{
{Public: crypto.PublicKey(cert.PublicKey), Certificate: cert}, {Public: crypto.PublicKey(cert.PublicKey), Certificate: cert, handle: commonRSAEkEquivalentHandle},
}, nil }, nil
} }
@ -133,23 +218,50 @@ func (t *wrappedTPM20) eks() ([]EK, error) {
if pub.RSAParameters == nil { if pub.RSAParameters == nil {
return nil, errors.New("ECC EK not yet supported") return nil, errors.New("ECC EK not yet supported")
} }
return []EK{
{ i, err := t.info()
Public: &rsa.PublicKey{ if err != nil {
return nil, fmt.Errorf("Retrieving TPM info failed: %v", err)
}
ekPub := &rsa.PublicKey{
E: int(pub.RSAParameters.Exponent()), E: int(pub.RSAParameters.Exponent()),
N: pub.RSAParameters.Modulus(), N: pub.RSAParameters.Modulus(),
}, }
var certificateURL string
if i.Manufacturer.String() == manufacturerIntel {
certificateURL = intelEKURL(ekPub)
}
return []EK{
{
Public: ekPub,
CertificateURL: certificateURL,
handle: commonRSAEkEquivalentHandle,
}, },
}, nil }, nil
} }
func (t *wrappedTPM20) newAK(opts *AKConfig) (*AK, error) { func (t *wrappedTPM20) newAK(opts *AKConfig) (*AK, error) {
// TODO(jsonp): Abstract choice of hierarchy & parent. var parent ParentKeyConfig
srk, _, err := t.getPrimaryKeyHandle(commonSrkEquivalentHandle) if opts != nil && opts.Parent != nil {
parent = *opts.Parent
} else {
parent = defaultParentConfig
}
srk, _, err := t.getStorageRootKeyHandle(parent)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get SRK handle: %v", err) return nil, fmt.Errorf("failed to get SRK handle: %v", err)
} }
var akTemplate tpm2.Public
var sigScheme *tpm2.SigScheme
// The default is RSA.
if opts != nil && opts.Algorithm == ECDSA {
akTemplate = akTemplateECC
sigScheme = akTemplateECC.ECCParameters.Sign
} else {
akTemplate = akTemplateRSA
sigScheme = akTemplateRSA.RSAParameters.Sign
}
blob, pub, creationData, creationHash, tix, err := tpm2.CreateKey(t.rwc, srk, tpm2.PCRSelection{}, "", "", akTemplate) blob, pub, creationData, creationHash, tix, err := tpm2.CreateKey(t.rwc, srk, tpm2.PCRSelection{}, "", "", akTemplate)
if err != nil { if err != nil {
return nil, fmt.Errorf("CreateKeyEx() failed: %v", err) return nil, fmt.Errorf("CreateKeyEx() failed: %v", err)
@ -166,7 +278,7 @@ func (t *wrappedTPM20) newAK(opts *AKConfig) (*AK, error) {
}() }()
// We can only certify the creation immediately afterwards, so we cache the result. // We can only certify the creation immediately afterwards, so we cache the result.
attestation, sig, err := tpm2.CertifyCreation(t.rwc, "", keyHandle, keyHandle, nil, creationHash, tpm2.SigScheme{Alg: tpm2.AlgRSASSA, Hash: tpm2.AlgSHA256, Count: 0}, tix) attestation, sig, err := tpm2.CertifyCreation(t.rwc, "", keyHandle, keyHandle, nil, creationHash, *sigScheme, tix)
if err != nil { if err != nil {
return nil, fmt.Errorf("CertifyCreation failed: %v", err) return nil, fmt.Errorf("CertifyCreation failed: %v", err)
} }
@ -179,6 +291,15 @@ func (t *wrappedTPM20) newKey(ak *AK, opts *KeyConfig) (*Key, error) {
return nil, fmt.Errorf("expected *wrappedKey20, got: %T", k) return nil, fmt.Errorf("expected *wrappedKey20, got: %T", k)
} }
kAlg, err := k.algorithm()
if err != nil {
return nil, fmt.Errorf("get algorithm: %v", err)
}
ck := certifyingKey{handle: k.hnd, alg: kAlg}
return t.newKeyCertifiedByKey(ck, opts)
}
func (t *wrappedTPM20) newKeyCertifiedByKey(ck certifyingKey, opts *KeyConfig) (*Key, error) {
parent, blob, pub, creationData, err := createKey(t, opts) parent, blob, pub, creationData, err := createKey(t, opts)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot create key: %v", err) return nil, fmt.Errorf("cannot create key: %v", err)
@ -196,9 +317,10 @@ func (t *wrappedTPM20) newKey(ak *AK, opts *KeyConfig) (*Key, error) {
}() }()
// Certify application key by AK // Certify application key by AK
cp, err := k.certify(t, keyHandle) certifyOpts := CertifyOpts{QualifyingData: opts.QualifyingData}
cp, err := certifyByKey(t, keyHandle, ck, certifyOpts)
if err != nil { if err != nil {
return nil, fmt.Errorf("ak.Certify() failed: %v", err) return nil, fmt.Errorf("certifyByKey() failed: %v", err)
} }
if !bytes.Equal(pub, cp.Public) { if !bytes.Equal(pub, cp.Public) {
return nil, fmt.Errorf("certified incorrect key, expected: %v, certified: %v", pub, cp.Public) return nil, fmt.Errorf("certified incorrect key, expected: %v, certified: %v", pub, cp.Public)
@ -217,7 +339,13 @@ func (t *wrappedTPM20) newKey(ak *AK, opts *KeyConfig) (*Key, error) {
} }
func createKey(t *wrappedTPM20, opts *KeyConfig) (tpmutil.Handle, []byte, []byte, []byte, error) { func createKey(t *wrappedTPM20, opts *KeyConfig) (tpmutil.Handle, []byte, []byte, []byte, error) {
srk, _, err := t.getPrimaryKeyHandle(commonSrkEquivalentHandle) var parent ParentKeyConfig
if opts != nil && opts.Parent != nil {
parent = *opts.Parent
} else {
parent = defaultParentConfig
}
srk, _, err := t.getStorageRootKeyHandle(parent)
if err != nil { if err != nil {
return 0, nil, nil, nil, fmt.Errorf("failed to get SRK handle: %v", err) return 0, nil, nil, nil, fmt.Errorf("failed to get SRK handle: %v", err)
} }
@ -282,7 +410,7 @@ func templateFromConfig(opts *KeyConfig) (tpm2.Public, error) {
return tmpl, nil return tmpl, nil
} }
func (t *wrappedTPM20) deserializeAndLoad(opaqueBlob []byte) (tpmutil.Handle, *serializedKey, error) { func (t *wrappedTPM20) deserializeAndLoad(opaqueBlob []byte, parent ParentKeyConfig) (tpmutil.Handle, *serializedKey, error) {
sKey, err := deserializeKey(opaqueBlob, TPMVersion20) sKey, err := deserializeKey(opaqueBlob, TPMVersion20)
if err != nil { if err != nil {
return 0, nil, fmt.Errorf("deserializeKey() failed: %v", err) return 0, nil, fmt.Errorf("deserializeKey() failed: %v", err)
@ -291,7 +419,7 @@ func (t *wrappedTPM20) deserializeAndLoad(opaqueBlob []byte) (tpmutil.Handle, *s
return 0, nil, fmt.Errorf("unsupported key encoding: %x", sKey.Encoding) return 0, nil, fmt.Errorf("unsupported key encoding: %x", sKey.Encoding)
} }
srk, _, err := t.getPrimaryKeyHandle(commonSrkEquivalentHandle) srk, _, err := t.getStorageRootKeyHandle(parent)
if err != nil { if err != nil {
return 0, nil, fmt.Errorf("failed to get SRK handle: %v", err) return 0, nil, fmt.Errorf("failed to get SRK handle: %v", err)
} }
@ -303,7 +431,11 @@ func (t *wrappedTPM20) deserializeAndLoad(opaqueBlob []byte) (tpmutil.Handle, *s
} }
func (t *wrappedTPM20) loadAK(opaqueBlob []byte) (*AK, error) { func (t *wrappedTPM20) loadAK(opaqueBlob []byte) (*AK, error) {
hnd, sKey, err := t.deserializeAndLoad(opaqueBlob) return t.loadAKWithParent(opaqueBlob, defaultParentConfig)
}
func (t *wrappedTPM20) loadAKWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*AK, error) {
hnd, sKey, err := t.deserializeAndLoad(opaqueBlob, parent)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot load attestation key: %v", err) return nil, fmt.Errorf("cannot load attestation key: %v", err)
} }
@ -311,7 +443,11 @@ func (t *wrappedTPM20) loadAK(opaqueBlob []byte) (*AK, error) {
} }
func (t *wrappedTPM20) loadKey(opaqueBlob []byte) (*Key, error) { func (t *wrappedTPM20) loadKey(opaqueBlob []byte) (*Key, error) {
hnd, sKey, err := t.deserializeAndLoad(opaqueBlob) return t.loadKeyWithParent(opaqueBlob, defaultParentConfig)
}
func (t *wrappedTPM20) loadKeyWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*Key, error) {
hnd, sKey, err := t.deserializeAndLoad(opaqueBlob, parent)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot load signing key: %v", err) return nil, fmt.Errorf("cannot load signing key: %v", err)
} }
@ -326,6 +462,10 @@ func (t *wrappedTPM20) loadKey(opaqueBlob []byte) (*Key, error) {
return &Key{key: newWrappedKey20(hnd, sKey.Blob, sKey.Public, sKey.CreateData, sKey.CreateAttestation, sKey.CreateSignature), pub: pub, tpm: t}, nil return &Key{key: newWrappedKey20(hnd, sKey.Blob, sKey.Public, sKey.CreateData, sKey.CreateAttestation, sKey.CreateSignature), pub: pub, tpm: t}, nil
} }
func (t *wrappedTPM20) pcrbanks() ([]HashAlg, error) {
return pcrbanks(t.rwc)
}
func (t *wrappedTPM20) pcrs(alg HashAlg) ([]PCR, error) { func (t *wrappedTPM20) pcrs(alg HashAlg) ([]PCR, error) {
PCRs, err := readAllPCRs20(t.rwc, alg.goTPMAlg()) PCRs, err := readAllPCRs20(t.rwc, alg.goTPMAlg())
if err != nil { if err != nil {
@ -402,7 +542,7 @@ func (k *wrappedKey20) close(t tpmBase) error {
return tpm2.FlushContext(tpm.rwc, k.hnd) return tpm2.FlushContext(tpm.rwc, k.hnd)
} }
func (k *wrappedKey20) activateCredential(tb tpmBase, in EncryptedCredential) ([]byte, error) { func (k *wrappedKey20) activateCredential(tb tpmBase, in EncryptedCredential, ek *EK) ([]byte, error) {
t, ok := tb.(*wrappedTPM20) t, ok := tb.(*wrappedTPM20)
if !ok { if !ok {
return nil, fmt.Errorf("expected *wrappedTPM20, got %T", tb) return nil, fmt.Errorf("expected *wrappedTPM20, got %T", tb)
@ -417,7 +557,7 @@ func (k *wrappedKey20) activateCredential(tb tpmBase, in EncryptedCredential) ([
} }
secret := in.Secret[2:] secret := in.Secret[2:]
ekHnd, _, err := t.getPrimaryKeyHandle(commonRSAEkEquivalentHandle) ekHnd, _, err := t.getEndorsementKeyHandle(ek)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -446,7 +586,36 @@ func (k *wrappedKey20) activateCredential(tb tpmBase, in EncryptedCredential) ([
}, k.hnd, ekHnd, credential, secret) }, k.hnd, ekHnd, credential, secret)
} }
func (k *wrappedKey20) certify(tb tpmBase, handle interface{}) (*CertificationParameters, error) { func sigSchemeFromAlgorithm(alg Algorithm) (tpm2.SigScheme, error) {
switch alg {
case RSA:
return tpm2.SigScheme{
Alg: tpm2.AlgRSASSA,
Hash: tpm2.AlgSHA256,
}, nil
case ECDSA:
return tpm2.SigScheme{
Alg: tpm2.AlgECDSA,
Hash: tpm2.AlgSHA256,
}, nil
default:
return tpm2.SigScheme{}, fmt.Errorf("algorithm %v not supported", alg)
}
}
func (k *wrappedKey20) certify(tb tpmBase, handle interface{}, opts CertifyOpts) (*CertificationParameters, error) {
kAlg, err := k.algorithm()
if err != nil {
return nil, fmt.Errorf("unknown algorithm: %v", err)
}
ck := certifyingKey{
handle: k.hnd,
alg: kAlg,
}
return certifyByKey(tb, handle, ck, opts)
}
func certifyByKey(tb tpmBase, handle interface{}, ck certifyingKey, opts CertifyOpts) (*CertificationParameters, error) {
t, ok := tb.(*wrappedTPM20) t, ok := tb.(*wrappedTPM20)
if !ok { if !ok {
return nil, fmt.Errorf("expected *wrappedTPM20, got %T", tb) return nil, fmt.Errorf("expected *wrappedTPM20, got %T", tb)
@ -455,19 +624,19 @@ func (k *wrappedKey20) certify(tb tpmBase, handle interface{}) (*CertificationPa
if !ok { if !ok {
return nil, fmt.Errorf("expected tpmutil.Handle, got %T", handle) return nil, fmt.Errorf("expected tpmutil.Handle, got %T", handle)
} }
scheme := tpm2.SigScheme{ scheme, err := sigSchemeFromAlgorithm(ck.alg)
Alg: tpm2.AlgRSASSA, if err != nil {
Hash: tpm2.AlgSHA256, return nil, fmt.Errorf("get signature scheme: %v", err)
} }
return certify(t.rwc, hnd, k.hnd, scheme) return certify(t.rwc, hnd, ck.handle, opts.QualifyingData, scheme)
} }
func (k *wrappedKey20) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, error) { func (k *wrappedKey20) quote(tb tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error) {
t, ok := tb.(*wrappedTPM20) t, ok := tb.(*wrappedTPM20)
if !ok { if !ok {
return nil, fmt.Errorf("expected *wrappedTPM20, got %T", tb) return nil, fmt.Errorf("expected *wrappedTPM20, got %T", tb)
} }
return quote20(t.rwc, k.hnd, tpm2.Algorithm(alg), nonce) return quote20(t.rwc, k.hnd, tpm2.Algorithm(alg), nonce, selectedPCRs)
} }
func (k *wrappedKey20) attestationParameters() AttestationParameters { func (k *wrappedKey20) attestationParameters() AttestationParameters {
@ -513,7 +682,9 @@ func signECDSA(rw io.ReadWriter, key tpmutil.Handle, digest []byte, curve ellipt
if excess > 0 { if excess > 0 {
ret.Rsh(ret, uint(excess)) ret.Rsh(ret, uint(excess))
} }
digest = ret.Bytes() // call ret.FillBytes() here instead of ret.Bytes() to preserve leading zeroes
// that may have been dropped when converting the digest to an integer
digest = ret.FillBytes(digest)
sig, err := tpm2.Sign(rw, key, "", digest, nil, nil) sig, err := tpm2.Sign(rw, key, "", digest, nil, nil)
if err != nil { if err != nil {
@ -563,3 +734,18 @@ func (k *wrappedKey20) decrypt(tb tpmBase, ctxt []byte) ([]byte, error) {
func (k *wrappedKey20) blobs() ([]byte, []byte, error) { func (k *wrappedKey20) blobs() ([]byte, []byte, error) {
return k.public, k.blob, nil return k.public, k.blob, nil
} }
func (k *wrappedKey20) algorithm() (Algorithm, error) {
tpmPub, err := tpm2.DecodePublic(k.public)
if err != nil {
return "", fmt.Errorf("decode public key: %v", err)
}
switch tpmPub.Type {
case tpm2.AlgRSA:
return RSA, nil
case tpm2.AlgECC:
return ECDSA, nil
default:
return "", fmt.Errorf("unsupported key type: %v", tpmPub.Type)
}
}

View File

@ -37,6 +37,7 @@ var (
oidSignatureRSASha1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} oidSignatureRSASha1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10} oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
oidSignatureRSASha256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} oidSignatureRSASha256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
oidSignatureRSASha384 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112} oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
@ -55,6 +56,7 @@ var signatureAlgorithmDetails = []struct {
}{ }{
{x509.SHA1WithRSA, "SHA1-RSA", oidSignatureRSASha1, x509.RSA, crypto.SHA1}, {x509.SHA1WithRSA, "SHA1-RSA", oidSignatureRSASha1, x509.RSA, crypto.SHA1},
{x509.SHA256WithRSA, "SHA256-RSA", oidSignatureRSASha256, x509.RSA, crypto.SHA256}, {x509.SHA256WithRSA, "SHA256-RSA", oidSignatureRSASha256, x509.RSA, crypto.SHA256},
{x509.SHA384WithRSA, "SHA384-RSA", oidSignatureRSASha384, x509.RSA, crypto.SHA384},
{x509.SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA256}, {x509.SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA256},
{x509.SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA384}, {x509.SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA384},
{x509.SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA512}, {x509.SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA512},

15
go.mod
View File

@ -1,16 +1,19 @@
module github.com/google/go-attestation module github.com/google/go-attestation
go 1.20 go 1.24
toolchain go1.24.1
require ( require (
github.com/google/go-cmp v0.5.9 github.com/google/go-cmp v0.7.0
github.com/google/go-tpm v0.9.0 github.com/google/go-tpm v0.9.3
github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba github.com/google/go-tpm-tools v0.4.5
github.com/google/go-tspi v0.3.0 github.com/google/go-tspi v0.3.0
golang.org/x/sys v0.9.0 go.uber.org/multierr v1.11.0
golang.org/x/sys v0.31.0
) )
require ( require (
github.com/google/certificate-transparency-go v1.1.2 // indirect github.com/google/certificate-transparency-go v1.1.2 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect golang.org/x/crypto v0.31.0 // indirect
) )

48
go.sum
View File

@ -173,6 +173,7 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
@ -296,27 +297,29 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-configfs-tsm v0.3.3-0.20240919001351-b4b5b84fdcbc h1:SG12DWUUM5igxm+//YX5Yq4vhdoRnOG9HkCodkOn+YU=
github.com/google/go-configfs-tsm v0.3.3-0.20240919001351-b4b5b84fdcbc/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo=
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
github.com/google/go-licenses v0.0.0-20210329231322-ce1d9163b77d/go.mod h1:+TYOmkVoJOpwnS0wfdsJCV9CoD5nJYsHoFk/0CrTK4M= github.com/google/go-licenses v0.0.0-20210329231322-ce1d9163b77d/go.mod h1:+TYOmkVoJOpwnS0wfdsJCV9CoD5nJYsHoFk/0CrTK4M=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no=
github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= github.com/google/go-sev-guest v0.12.1 h1:H4rFYnPIn8HtqEsNTmh56Zxcf9BI9n48ZSYCnpYLYvc=
github.com/google/go-tpm v0.3.4-0.20230613064043-511507721cb1 h1:wGP91a6fiYbZhKlGcQD25K8XwXzoG4yHAEIjtpeV2QA= github.com/google/go-sev-guest v0.12.1/go.mod h1:SK9vW+uyfuzYdVN0m8BShL3OQCtXZe/JPF7ZkpD3760=
github.com/google/go-tpm v0.3.4-0.20230613064043-511507721cb1/go.mod h1:Yj9bYgsIKoza8oMlxZqvqgUIDKFaExnuLaDdOtFCwG4= github.com/google/go-tdx-guest v0.3.2-0.20241009005452-097ee70d0843 h1:+MoPobRN9HrDhGyn6HnF5NYo4uMBKaiFqAtf/D/OB4A=
github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= github.com/google/go-tdx-guest v0.3.2-0.20241009005452-097ee70d0843/go.mod h1:g/n8sKITIT9xRivBUbizo34DTsUm2nN2uU3A662h09g=
github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= github.com/google/go-tpm v0.9.3 h1:+yx0/anQuGzi+ssRqeD6WpXjW2L/V0dItUayO0i9sRc=
github.com/google/go-tpm-tools v0.3.12 h1:hpWglH4RaZnGVbgOK3IThI5K++jnFvjQ94EIN34xrUU= github.com/google/go-tpm v0.9.3/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
github.com/google/go-tpm-tools v0.3.12/go.mod h1:2OtmyPGPuaWWIOjr+IDhNQb6t5njjbSmZtzc350Q6Ro= github.com/google/go-tpm-tools v0.4.5 h1:3fhthtyMDbIZFR5/0y1hvUoZ1Kf4i1eZ7C73R4Pvd+k=
github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= github.com/google/go-tpm-tools v0.4.5/go.mod h1:ktjTNq8yZFD6TzdBFefUfen96rF3NpYwpSb2d8bc+Y8=
github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc=
github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus=
github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/licenseclassifier v0.0.0-20210325184830-bb04aff29e72/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M= github.com/google/licenseclassifier v0.0.0-20210325184830-bb04aff29e72/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M=
github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ=
github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@ -347,7 +350,8 @@ github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4Mgqvf
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs16741s= github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs16741s=
github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
@ -536,7 +540,6 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9
github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@ -545,10 +548,10 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@ -646,6 +649,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0= github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
@ -732,6 +737,8 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
@ -753,8 +760,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -946,8 +953,8 @@ golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1191,7 +1198,8 @@ google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX7
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -1222,6 +1230,8 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -149,8 +149,9 @@ func forEachSAN(extension []byte, callback func(ext asn1.RawValue) error) error
return nil return nil
} }
// MarshalSubjectAltName converts a SubjectAltName struct into a pkix.Extension. // MarshalSubjectAltName converts a SubjectAltName struct into a pkix.Extension,
func MarshalSubjectAltName(san *SubjectAltName) (pkix.Extension, error) { // allowing callers to specify if the extension is critical.
func MarshalSubjectAltName(san *SubjectAltName, critical bool) (pkix.Extension, error) {
var generalNames []asn1.RawValue var generalNames []asn1.RawValue
for _, permID := range san.PermanentIdentifiers { for _, permID := range san.PermanentIdentifiers {
val, err := marshalOtherName(oidPermanentIdentifier, permID) val, err := marshalOtherName(oidPermanentIdentifier, permID)
@ -172,6 +173,7 @@ func MarshalSubjectAltName(san *SubjectAltName) (pkix.Extension, error) {
} }
return pkix.Extension{ return pkix.Extension{
Id: oid.SubjectAltName, Id: oid.SubjectAltName,
Critical: critical,
Value: val, Value: val,
}, nil }, nil
} }