Skip to content

Commit 5741fff

Browse files
committed
re add unmanaged for long running use (https server)
1 parent eca8b24 commit 5741fff

File tree

6 files changed

+435
-24
lines changed

6 files changed

+435
-24
lines changed

README.md

+59-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ see the [example/](example/) folder for more information.
2121

2222
---
2323

24-
>> **NOTE** there will be a breaking change if you are using this library for TPM based signature after `v0.8.0`. The new structure uses the [tpm-direct](https://github.com/google/go-tpm/releases/tag/v0.9.0) API. If you would rather use the tpm2/legacy branch, please use the signer at [v0.7.2](https://github.com/salrashid123/signer/releases/tag/v0.7.2). This change also *removes* the library managed device. The caller must provide a pre-authorized key (there was no way the library could authorize the variety of auth sessions...it must be provided in)
2524

2625

2726
>> this library is not supported by google
@@ -70,8 +69,66 @@ go run certgen/certgen.go -cn server.domain.com
7069

7170
---
7271

73-
7472
If you just want to issue JWT's, see
7573

7674
* [https://github.com/salrashid123/golang-jwt-tpm](https://github.com/salrashid123/golang-jwt-tpm)
7775
* [https://github.com/salrashid123/golang-jwt-pkcs11](https://github.com/salrashid123/golang-jwt-pkcs11)
76+
77+
78+
### TPM Signer Device management
79+
80+
>> **NOTE** there will be a breaking change if you are using this library for TPM based signature after `v0.8.0`. The new structure uses the [tpm-direct](https://github.com/google/go-tpm/releases/tag/v0.9.0) API. If you would rather use the tpm2/legacy branch, please use the signer at [v0.7.2](https://github.com/salrashid123/signer/releases/tag/v0.7.2). While this repo still retain managed and unmanaged handles to the TPM device, its recommended to to manage it externally if you need complex authorization...if its simple authorization like pcr and password or if you need concurrent, non blocking of the TPM device, use library managed handle. For externally manged, just remember to open-sign-close as the device is locking.
81+
82+
For TPM Signer, there are two modes of operation:
83+
84+
* managed externally
85+
86+
The TPM device is managed externally outside of the signer. You have to instantiate the TPM device ReadWriteCloser and client.Key outside of the library and pass that in.
87+
88+
The advantage of this is you control it opening and closing. You must close the key and closer before calling another signing operation. THis sounds ok but is problematic when dealing with long-running processes which may need to hang on to the tpm (for example you use the singer for an TLS server)
89+
90+
if you want to manage it externally,
91+
92+
```golang
93+
// this blocks access to the tpm by other processes
94+
// until rwc.Close() is closed
95+
rwc, err := OpenTPM(*tpmPath)
96+
rwr := transport.FromReadWriter(rwc)
97+
98+
pub, err := tpm2.ReadPublic{
99+
ObjectHandle: tpm2.TPMHandle(*handle),
100+
}.Execute(rwr)
101+
102+
r, err := saltpm.NewTPMCrypto(&saltpm.TPM{
103+
TpmDevice: rwc,
104+
AuthHandle: &tpm2.AuthHandle{
105+
Handle: tpm2.TPMHandle(*handle),
106+
Name: pub.Name,
107+
Auth: tpm2.PasswordAuth(nil),
108+
},
109+
})
110+
// the tpm is opened and then closed after every sign operation
111+
s, err := r.Sign(rand.Reader, digest, crypto.SHA256)
112+
```
113+
114+
* managed by library
115+
116+
This is the preferred mode: you just pass the uint32 handle for the key and the path to the tpm device as string and the library opens/closes it as needed.
117+
118+
If the device is busy or the TPM is in use during invocation, the operation will fail.
119+
120+
121+
```golang
122+
r, err := saltpm.NewTPMCrypto(&saltpm.TPM{
123+
TpmPath: *tpmPath,
124+
KeyHandle: tpm2.TPMHandle(*handle).HandleValue(),
125+
PCRs: []uint{},
126+
AuthPassword: []byte(""),
127+
})
128+
129+
// the tpm is opened and then closed after every sign operation
130+
s, err := r.Sign(rand.Reader, digest, crypto.SHA256)
131+
```
132+
133+
TODO use a backoff retry similar to [tpmrand](https://github.com/salrashid123/tpmrand) to prevent contention.
134+

example/README.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,13 @@ export TPM2TOOLS_TCTI="swtpm:port=2321"
118118

119119
## =====
120120

121-
cd example
121+
cd example/
122+
123+
## RSA-SSA managed externally
124+
go run sign_verify_tpm/rsassa/main.go --handle=0x81008001
122125

123-
## RSA-SSA
124-
go run sign_verify_tpm/rsassa/main.go --handle=0x81008001
126+
## RSA-SSA managed by library
127+
go run sign_verify_tpm/rsassa_managed/main.go --handle=0x81008001
125128

126129
## RSA-PSS
127130
go run sign_verify_tpm/rsapss/main.go --handle=0x81008004
@@ -131,7 +134,6 @@ go run sign_verify_tpm/ecc/main.go --handle=0x81008005
131134

132135
## RSA with policy
133136
go run sign_verify_tpm/policy/main.go --handle=0x81008006
134-
135137
```
136138

137139

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package main
2+
3+
import (
4+
"crypto"
5+
"crypto/rand"
6+
"crypto/rsa"
7+
"crypto/sha256"
8+
"encoding/base64"
9+
"flag"
10+
"fmt"
11+
"io"
12+
"log"
13+
"net"
14+
"os"
15+
"slices"
16+
17+
"github.com/google/go-tpm-tools/simulator"
18+
"github.com/google/go-tpm/tpm2"
19+
"github.com/google/go-tpm/tpmutil"
20+
saltpm "github.com/salrashid123/signer/tpm"
21+
)
22+
23+
const ()
24+
25+
var (
26+
tpmPath = flag.String("tpm-path", "127.0.0.1:2321", "Path to the TPM device (character device or a Unix socket).")
27+
handle = flag.Uint("handle", 0x81008001, "rsa Handle value")
28+
)
29+
30+
var TPMDEVICES = []string{"/dev/tpm0", "/dev/tpmrm0"}
31+
32+
func OpenTPM(path string) (io.ReadWriteCloser, error) {
33+
if slices.Contains(TPMDEVICES, path) {
34+
return tpmutil.OpenTPM(path)
35+
} else if path == "simulator" {
36+
return simulator.GetWithFixedSeedInsecure(1073741825)
37+
} else {
38+
return net.Dial("tcp", path)
39+
}
40+
}
41+
42+
func main() {
43+
44+
flag.Parse()
45+
46+
stringToSign := "foo"
47+
fmt.Printf("Data to sign %s\n", stringToSign)
48+
49+
b := []byte(stringToSign)
50+
51+
h := sha256.New()
52+
h.Write(b)
53+
digest := h.Sum(nil)
54+
55+
r, err := saltpm.NewTPMCrypto(&saltpm.TPM{
56+
TpmPath: *tpmPath,
57+
KeyHandle: tpm2.TPMHandle(*handle).HandleValue(),
58+
PCRs: []uint{},
59+
AuthPassword: []byte(""),
60+
})
61+
62+
if err != nil {
63+
fmt.Println(err)
64+
os.Exit(1)
65+
}
66+
67+
s, err := r.Sign(rand.Reader, digest, crypto.SHA256)
68+
if err != nil {
69+
log.Println(err)
70+
os.Exit(1)
71+
}
72+
fmt.Printf("RSA Signed String: %s\n", base64.StdEncoding.EncodeToString(s))
73+
74+
rsaPubKey, ok := r.Public().(*rsa.PublicKey)
75+
if !ok {
76+
fmt.Println(err)
77+
os.Exit(1)
78+
}
79+
80+
err = rsa.VerifyPKCS1v15(rsaPubKey, crypto.SHA256, digest, s)
81+
if err != nil {
82+
fmt.Println(err)
83+
os.Exit(1)
84+
}
85+
fmt.Printf("RSA Signed String verified\n")
86+
87+
}

0 commit comments

Comments
 (0)