1
- #### crypto.Signer, implementations for Google Cloud KMS and Trusted Platform Modules
1
+ #### crypto.Signer, implementations for Trusted Platform Modules
2
2
3
3
where private keys as embedded inside:
4
4
5
- * ` Google Cloud KMS `
6
5
* ` Trusted Platform Module (TPM) `
7
6
8
7
Basically, you will get a ` crypto.Signer ` interface where the private keys are saved on those platform.
9
8
10
9
Use the signer to create a TLS session, sign CA/CSRs, generate signed url or just sign anything.
11
10
12
- Some implementations:
13
-
14
- - ` kms/ ` : Sample that implements ` crypto.Signer ` using Google Cloud KMS.
15
- - ` tpm/ ` : Sample that implements ` crypto.Signer ` using ` go-tpm ` library for Trusted Platform Module.
16
-
17
- other stuff:
11
+ For example, you can use this to sign data or to generate certificates/csr or for mTLS.
18
12
19
13
- ` util/certgen/ ` : Library that generates a self-signed x509 certificate for the KMS and TPM based signers above
20
14
- ` util/csrgen/ ` : Library that generates a CSR using the key in KMS or TPM
@@ -37,7 +31,6 @@ Initialize a signer and directly use `.sign()` as shown in this sample for GCS S
37
31
### Usage TLS
38
32
39
33
* for tpm see [ mTLS with TPM bound private key] ( https://github.com/salrashid123/go_tpm_https_embed )
40
- * for kms see [ mTLS with Google Cloud KMS] ( https://github.com/salrashid123/kms_golang_signer )
41
34
42
35
### Sign/Verify PSS
43
36
@@ -112,3 +105,184 @@ If you just want to issue JWT's, see
112
105
113
106
TODO use a backoff retry similar to [ tpmrand] ( https://github.com/salrashid123/tpmrand ) to prevent contention.
114
107
108
+ ---
109
+
110
+
111
+
112
+ ### Example Setup - TPM
113
+
114
+
115
+ example usage generates a new TPM unrestricted RSA key and sign,verify some data.
116
+
117
+
118
+ You can create the persistent handles using go-tpm or using ` tpm2_tools ` and make it persistent,
119
+
120
+ First install latest ` tpm2_tools `
121
+
122
+ ``` bash
123
+ # # install latest tpm2-tools:
124
+ # ### https://github.com/salrashid123/tpm2/tree/master?tab=readme-ov-file#installing-tpm2_tools-golang
125
+ # ### https://tpm2-tools.readthedocs.io/en/latest/INSTALL/
126
+ ```
127
+
128
+ ``` bash
129
+ cd example/
130
+
131
+ # # if you want to use a software TPM,
132
+ # rm -rf /tmp/myvtpm && mkdir /tmp/myvtpm
133
+ # sudo swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear
134
+
135
+ # # then specify "127.0.0.1:2321" as the TPM device path in the examples
136
+ # # then for tpm2_tools, export the following var
137
+ # export TPM2TOOLS_TCTI="swtpm:port=2321"
138
+
139
+ # # note if you want, the primary can be the "H2" profile from https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html#name-parent
140
+ # printf '\x00\x00' > unique.dat
141
+ # tpm2_createprimary -C o -G ecc -g sha256 -c primary.ctx -a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|decrypt" -u unique.dat
142
+
143
+
144
+ # # RSA - no password
145
+ tpm2_createprimary -C o -G rsa2048:aes128cfb -g sha256 -c primary.ctx -a ' restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda'
146
+ tpm2_create -G rsa2048:rsassa:null -g sha256 -u key.pub -r key.priv -C primary.ctx
147
+ tpm2_getcap handles-transient
148
+ tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx
149
+ tpm2_evictcontrol -C o -c key.ctx 0x81008001
150
+
151
+ # ## RSA - no password with PEM key file
152
+
153
+ printf ' \x00\x00' > unique.dat
154
+ tpm2_createprimary -C o -G ecc -g sha256 -c primary.ctx -a " fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|decrypt" -u unique.dat
155
+
156
+ tpm2_create -G rsa2048:rsapss:null -g sha256 -u key.pub -r key.priv -C primary.ctx --format=pem --output=rsapss_public.pem
157
+ tpm2_getcap handles-transient
158
+ tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx
159
+ tpm2_encodeobject -C primary.ctx -u key.pub -r key.priv -o key.pem
160
+
161
+ # # rsa-pss
162
+ tpm2_createprimary -C o -G rsa2048:aes128cfb -g sha256 -c primary.ctx -a ' restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda'
163
+ tpm2_getcap handles-transient
164
+ tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx
165
+ tpm2_evictcontrol -C o -c key.ctx 0x81008004
166
+
167
+ # # ecc
168
+ tpm2_createprimary -C o -G rsa2048:aes128cfb -g sha256 -c primary.ctx -a ' restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda'
169
+ tpm2_create -G ecc:ecdsa -g sha256 -u key.pub -r key.priv -C primary.ctx --format=pem --output=ecc_public.pem
170
+ tpm2_getcap handles-transient
171
+ tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx
172
+ tpm2_evictcontrol -C o -c key.ctx 0x81008005
173
+
174
+ # # for policyPCR
175
+
176
+ tpm2_pcrread sha256:23
177
+ tpm2_startauthsession -S session.dat
178
+ tpm2_policypcr -S session.dat -l sha256:23 -L policy.dat
179
+ tpm2_flushcontext session.dat
180
+ tpm2_createprimary -C o -G rsa2048:aes128cfb -g sha256 -c primary.ctx -a ' restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda'
181
+ tpm2_create -G rsa2048:rsassa:null -g sha256 -u key.pub -r key.priv -C primary.ctx -L policy.dat
182
+ tpm2_getcap handles-transient
183
+ tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx
184
+ tpm2_evictcontrol -C o -c key.ctx 0x81008006
185
+
186
+ # # for policyPassword
187
+
188
+ tpm2_createprimary -C o -G rsa2048:aes128cfb -g sha256 -c primary.ctx -a ' restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda'
189
+ tpm2_create -G rsa2048:rsassa:null -p testpwd -g sha256 -u key.pub -r key.priv -C primary.ctx
190
+ tpm2_getcap handles-transient
191
+ tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx
192
+ tpm2_evictcontrol -C o -c key.ctx 0x81008007
193
+
194
+ # # =====
195
+
196
+ cd example/
197
+
198
+ # # RSA-SSA managed externally
199
+ go run sign_verify_tpm/rsassa/main.go --handle=0x81008001 --tpm-path=" 127.0.0.1:2321"
200
+
201
+ # # RSA-PSS
202
+ go run sign_verify_tpm/rsapss/main.go --handle=0x81008004 --tpm-path=" 127.0.0.1:2321"
203
+
204
+ # # ECC
205
+ go run sign_verify_tpm/ecc/main.go --handle=0x81008005 --tpm-path=" 127.0.0.1:2321"
206
+
207
+ # # RSA with pcr policy
208
+ go run sign_verify_tpm/policy_pcr/main.go --handle=0x81008006 --tpm-path=" 127.0.0.1:2321"
209
+
210
+ # # RSA with password policy
211
+ go run sign_verify_tpm/policy_password/main.go --handle=0x81008007 --tpm-path=" 127.0.0.1:2321"
212
+ ```
213
+
214
+ Note, you can define your own policy for import too...just implement the "session" interface from the signer:
215
+
216
+ ``` golang
217
+ type Session interface {
218
+ GetSession () (auth tpm2.Session , closer func () error , err error ) // this supplies the session handle to the library
219
+ }
220
+ ```
221
+
222
+ for example, for a PCR and [ AuthPolicy] ( https://github.com/google/go-tpm/pull/359 ) enforcement (eg, a PCR and password), you can define a custom session callback
223
+
224
+ ``` golang
225
+ type MyPCRAndPolicyAuthValueSession struct {
226
+ rwr transport.TPM
227
+ sel []tpm2.TPMSPCRSelection
228
+ password []byte
229
+ }
230
+
231
+ func NewPCRAndPolicyAuthValueSession (rwr transport .TPM , sel []tpm2 .TPMSPCRSelection , password []byte ) (MyPCRAndPolicyAuthValueSession , error ) {
232
+ return MyPCRAndPolicyAuthValueSession{rwr, sel, password}, nil
233
+ }
234
+
235
+ func (p MyPCRAndPolicyAuthValueSession ) GetSession () (auth tpm2 .Session , closer func () error, err error) {
236
+
237
+ var options []tpm2.AuthOption
238
+ options = append (options, tpm2.Auth (p.password ))
239
+
240
+ sess , closer , err := tpm2.PolicySession (p.rwr , tpm2.TPMAlgSHA256 , 16 , options...)
241
+ if err != nil {
242
+ return nil , nil , err
243
+ }
244
+
245
+ _, err = tpm2.PolicyPCR {
246
+ PolicySession: sess.Handle (),
247
+ Pcrs: tpm2.TPMLPCRSelection {
248
+ PCRSelections: p.sel ,
249
+ },
250
+ }.Execute (p.rwr )
251
+ if err != nil {
252
+ return nil , nil , err
253
+ }
254
+
255
+ _, err = tpm2.PolicyAuthValue {
256
+ PolicySession: sess.Handle (),
257
+ }.Execute (p.rwr )
258
+ if err != nil {
259
+ return nil , nil , err
260
+ }
261
+
262
+ return sess, closer, nil
263
+ }
264
+
265
+ ```
266
+
267
+ which you can call as:
268
+
269
+ ``` golang
270
+ se , err := NewPCRAndPolicyAuthValueSession (rwr, []tpm2.TPMSPCRSelection {
271
+ {
272
+ Hash: tpm2.TPMAlgSHA256 ,
273
+ PCRSelect: tpm2.PCClientCompatible .PCRs (uint (*pcr)),
274
+ },
275
+ }, []byte (" testpswd" ))
276
+
277
+ rr , err := saltpm.NewTPMCrypto (&saltpm.TPM {
278
+ TpmDevice : rwc,
279
+ NamedHandle : &tpm2.NamedHandle {
280
+ Handle: tpm2.TPMHandle (*handle),
281
+ Name: pub.Name ,
282
+ },
283
+ AuthSession : se,
284
+ })
285
+ ```
286
+
287
+ ---
288
+
0 commit comments