forked from canonical/secboot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherrors.go
174 lines (143 loc) · 7.22 KB
/
errors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2019 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package secboot
import (
"bytes"
"errors"
"fmt"
"github.com/canonical/go-tpm2"
"golang.org/x/xerrors"
)
var (
// ErrTPMClearRequiresPPI is returned from TPMConnection.EnsureProvisioned and indicates that clearing the TPM must be performed via
// the Physical Presence Interface.
ErrTPMClearRequiresPPI = errors.New("clearing the TPM requires the use of the Physical Presence Interface")
// ErrTPMProvisioningRequiresLockout is returned from TPMConnection.EnsureProvisioned when fully provisioning the TPM requires
// the use of the lockout hierarchy. In this case, the provisioning steps that can be performed without the use of the lockout
// hierarchy are completed.
ErrTPMProvisioningRequiresLockout = errors.New("provisioning the TPM requires the use of the lockout hierarchy")
// ErrTPMProvisioning indicates that the TPM is not provisioned correctly for the requested operation. Please note that other errors
// that can be returned may also be caused by incomplete provisioning, as it is not always possible to detect incomplete or
// incorrect provisioning in all contexts.
ErrTPMProvisioning = errors.New("the TPM is not correctly provisioned")
// ErrTPMLockout is returned from any function when the TPM is in dictionary-attack lockout mode. Until
// the TPM exits lockout mode, the key will need to be recovered via a mechanism that is independent of
// the TPM (eg, a recovery key)
ErrTPMLockout = errors.New("the TPM is in DA lockout mode")
// ErrPINFail is returned from SealedKeyObject.UnsealFromTPM if the provided PIN is incorrect.
ErrPINFail = errors.New("the provided PIN is incorrect")
// ErrNoTPM2Device is returned from ConnectToDefaultTPM or SecureConnectToDefaultTPM if no TPM2 device is avaiable.
ErrNoTPM2Device = errors.New("no TPM2 device is available")
// ErrNoActivationData is returned from GetActivationDataFromKernel if no activation data was found in the user keyring for
// the specified block device.
ErrNoActivationData = errors.New("no activation data found for the specified device")
)
// TPMResourceExistsError is returned from any function that creates a persistent TPM resource if a resource already exists
// at the specified handle.
type TPMResourceExistsError struct {
Handle tpm2.Handle
}
func (e TPMResourceExistsError) Error() string {
return fmt.Sprintf("a resource already exists on the TPM at handle %v", e.Handle)
}
// AuthFailError is returned when an authorization check fails. The provided handle indicates the resource for which authorization
// failed. Whilst the error normally indicates that the provided authorization value is incorrect, it may also be returned
// for other reasons that would cause a HMAC check failure, such as a communication failure between the host CPU and the TPM
// or the name of a resource on the TPM not matching the name of the ResourceContext passed to the function that failed - this
// latter issue can occur when using a resource manager if another process accesses the TPM and makes changes to persistent
// resources or sessions.
type AuthFailError struct {
Handle tpm2.Handle
}
func (e AuthFailError) Error() string {
return fmt.Sprintf("cannot access resource at handle %v because an authorization check failed", e.Handle)
}
// EKCertVerificationError is returned from SecureConnectToDefaultTPM if verification of the EK certificate against the built-in
// root CA certificates fails, or the EK certificate does not have the correct properties, or the supplied certificate data cannot
// be unmarshalled correctly because it is invalid.
type EKCertVerificationError struct {
msg string
}
func (e EKCertVerificationError) Error() string {
return fmt.Sprintf("cannot verify the endorsement key certificate: %s", e.msg)
}
func isEKCertVerificationError(err error) bool {
var e EKCertVerificationError
return xerrors.As(err, &e)
}
// TPMVerificationError is returned from SecureConnectToDefaultTPM if the TPM cannot prove it is the device for which the verified
// EK certificate was issued.
type TPMVerificationError struct {
msg string
}
func (e TPMVerificationError) Error() string {
return fmt.Sprintf("cannot verify that the TPM is the device for which the supplied EK certificate was issued: %s", e.msg)
}
func isTPMVerificationError(err error) bool {
var e TPMVerificationError
return xerrors.As(err, &e)
}
// InvalidKeyFileError indicates that the provided key data file is invalid. This error may also be returned in some
// scenarious where the TPM is incorrectly provisioned, but it isn't possible to determine whether the error is with
// the provisioning status or because the key data file is invalid.
type InvalidKeyFileError struct {
msg string
}
func (e InvalidKeyFileError) Error() string {
return fmt.Sprintf("invalid key data file: %s", e.msg)
}
func isInvalidKeyFileError(err error) bool {
var e InvalidKeyFileError
return xerrors.As(err, &e)
}
// ActivateWithTPMSealedKeyError is returned from ActivateVolumeWithTPMSealedKey if activation with the TPM protected key failed.
type ActivateWithTPMSealedKeyError struct {
// TPMErr details the error that occurred during activation with the TPM sealed key.
TPMErr error
// RecoveryKeyUsageErr details the error that occurred during activation with the fallback recovery key, if activation with the recovery key
// was also unsuccessful.
RecoveryKeyUsageErr error
}
func (e *ActivateWithTPMSealedKeyError) Error() string {
if e.RecoveryKeyUsageErr != nil {
return fmt.Sprintf("cannot activate with TPM sealed key (%v) and activation with recovery key failed (%v)", e.TPMErr, e.RecoveryKeyUsageErr)
}
return fmt.Sprintf("cannot activate with TPM sealed key (%v) but activation with recovery key was successful", e.TPMErr)
}
// ActivateWithMultipleTPMSealedKeysError is returned from ActivateVolumeWithMultipleTPMSealedKeys if activation with the
// TPM protected keys failed.
type ActivateWithMultipleTPMSealedKeysError struct {
// TPMErrs details the errors that occurred during activation with the TPM sealed keys.
TPMErrs []error
// RecoveryKeyUsageErr details the error that occurred during activation with the fallback recovery key, if activation
// with the recovery key was also unsuccessful.
RecoveryKeyUsageErr error
}
func (e *ActivateWithMultipleTPMSealedKeysError) Error() string {
var s bytes.Buffer
fmt.Fprintf(&s, "cannot activate with TPM sealed keys:")
for _, err := range e.TPMErrs {
fmt.Fprintf(&s, "\n- %v", err)
}
if e.RecoveryKeyUsageErr != nil {
fmt.Fprintf(&s, "\nand activation with recovery key failed: %v", e.RecoveryKeyUsageErr)
} else {
fmt.Fprintf(&s, "\nbut activation with recovery key was successful")
}
return s.String()
}