Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: adds more specific log errors for amt activation #569

Merged
merged 2 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 30 additions & 26 deletions internal/local/activate.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (service *ProvisioningService) Activate() error {

controlMode, err := service.amtCommand.GetControlMode()
if err != nil {
return utils.AMTConnectionFailed
return utils.ActivationFailedGetControlMode
}
if controlMode != 0 {
log.Error("Device is already activated")
Expand Down Expand Up @@ -60,52 +60,52 @@ func (service *ProvisioningService) ActivateACM() error {
// Extract the provisioning certificate
certObject, fingerPrint, err := service.GetProvisioningCertObj()
if err != nil {
return utils.ActivationFailed
return err
}
// Check provisioning certificate is accepted by AMT
err = service.CompareCertHashes(fingerPrint)
if err != nil {
return utils.ActivationFailed
return err
}

generalSettings, err := service.interfacedWsmanMessage.GetGeneralSettings()
if err != nil {
return utils.ActivationFailed
return utils.ActivationFailedGeneralSettings
}

getHostBasedSetupResponse, err := service.interfacedWsmanMessage.GetHostBasedSetupService()
if err != nil {
return utils.ActivationFailed
return utils.ActivationFailedSetupService
}
decodedNonce := getHostBasedSetupResponse.Body.GetResponse.ConfigurationNonce
fwNonce, err := base64.StdEncoding.DecodeString(decodedNonce)
if err != nil {
return utils.ActivationFailed
return utils.ActivationFailedDecode64
}

err = service.injectCertificate(certObject.certChain)
if err != nil {
return utils.ActivationFailed
return err
}

nonce, err := service.generateNonce()
if err != nil {
return utils.ActivationFailed
return err
}

signedSignature, err := service.createSignedString(nonce, fwNonce, certObject.privateKey)
if err != nil {
return utils.ActivationFailed
return err
}

_, err = service.interfacedWsmanMessage.HostBasedSetupServiceAdmin(service.config.ACMSettings.AMTPassword, generalSettings.Body.GetResponse.DigestRealm, nonce, signedSignature)
if err != nil {
controlMode, err := service.amtCommand.GetControlMode()
if err != nil {
return utils.AMTConnectionFailed
return utils.ActivationFailedGetControlMode
}
if controlMode != 2 {
return utils.ActivationFailed
return utils.ActivationFailedControlMode
}
return nil
}
Expand All @@ -115,11 +115,11 @@ func (service *ProvisioningService) ActivateACM() error {
func (service *ProvisioningService) ActivateCCM() error {
generalSettings, err := service.interfacedWsmanMessage.GetGeneralSettings()
if err != nil {
return utils.ActivationFailed
return utils.ActivationFailedGeneralSettings
}
_, err = service.interfacedWsmanMessage.HostBasedSetupService(generalSettings.Body.GetResponse.DigestRealm, service.config.Password)
if err != nil {
return utils.ActivationFailed
return utils.ActivationFailedSetupService
}
log.Info("Status: Device activated in Client Control Mode")
return nil
Expand Down Expand Up @@ -163,11 +163,15 @@ func (service *ProvisioningService) GetProvisioningCertObj() (ProvisioningCertOb
func convertPfxToObject(pfxb64 string, passphrase string) (CertsAndKeys, error) {
pfx, err := base64.StdEncoding.DecodeString(pfxb64)
if err != nil {
return CertsAndKeys{}, err
return CertsAndKeys{}, utils.ActivationFailedDecode64
}
privateKey, certificate, extraCerts, err := pkcs12.DecodeChain(pfx, passphrase)
if err != nil {
return CertsAndKeys{}, errors.New("decrypting provisioning certificate failed")
if strings.Contains(err.Error(), "decryption password incorrect") {
return CertsAndKeys{}, utils.ActivationFailedWrongCertPass
}

return CertsAndKeys{}, utils.ActivationFailedInvalidProvCert
}
certs := append([]*x509.Certificate{certificate}, extraCerts...)
pfxOut := CertsAndKeys{certs: certs, keys: []interface{}{privateKey}}
Expand All @@ -177,10 +181,10 @@ func convertPfxToObject(pfxb64 string, passphrase string) (CertsAndKeys, error)

func dumpPfx(pfxobj CertsAndKeys) (ProvisioningCertObj, string, error) {
if len(pfxobj.certs) == 0 {
return ProvisioningCertObj{}, "", errors.New("no certificates found")
return ProvisioningCertObj{}, "", utils.ActivationFailedNoCertFound
}
if len(pfxobj.keys) == 0 {
return ProvisioningCertObj{}, "", errors.New("no private keys found")
return ProvisioningCertObj{}, "", utils.ActivationFailedNoPrivKeys
}
var provisioningCertificateObj ProvisioningCertObj
var certificateList []*CertificateObject
Expand All @@ -206,6 +210,10 @@ func dumpPfx(pfxobj CertsAndKeys) (ProvisioningCertObj, string, error) {
certificateList = append(certificateList, &certificateObject)
}

if fingerprint == "" {
return provisioningCertificateObj, "", utils.ActivationFailedNoRootCertFound
}

// Order the certificates from leaf to root
orderedCertificateList := orderCertificates(certificateList)

Expand Down Expand Up @@ -254,14 +262,14 @@ func orderCertificates(certificates []*CertificateObject) []*CertificateObject {
func (service *ProvisioningService) CompareCertHashes(fingerPrint string) error {
result, err := service.amtCommand.GetCertificateHashes()
if err != nil {
log.Error(err)
return utils.ActivationFailedGetCertHash
}
for _, v := range result {
if v.Hash == fingerPrint {
return nil
}
}
return errors.New("the root of the provisioning certificate does not match any of the trusted roots in AMT")
return utils.ActivationFailedProvCertNoMatch
}

func (service *ProvisioningService) injectCertificate(certChain []string) error {
Expand All @@ -273,9 +281,7 @@ func (service *ProvisioningService) injectCertificate(certChain []string) error

_, err := service.interfacedWsmanMessage.AddNextCertInChain(cert, isLeaf, isRoot)
if err != nil {
log.Error(err)
// TODO: check if this is the correct error to return
return errors.New("failed to add certificate to AMT")
return utils.ActivationFailedAddCert
}
}
return nil
Expand All @@ -285,8 +291,7 @@ func (service *ProvisioningService) generateNonce() ([]byte, error) {
nonce := make([]byte, 20)
// fills nonce with 20 random bytes
if _, err := rand.Read(nonce); err != nil {
log.Error("Error generating nonce:", err)
return nil, err
return nil, utils.ActivationFailedGenerateNonce
}
return nonce, nil
}
Expand Down Expand Up @@ -327,8 +332,7 @@ func (service *ProvisioningService) createSignedString(nonce []byte, fwNonce []b
arr := append(fwNonce, nonce...)
signature, err := service.signString(arr, privateKey)
if err != nil {
log.Error("Error signing string:", err)
return "", err
return "", utils.ActivationFailedSignString
}
return signature, nil
}
15 changes: 15 additions & 0 deletions pkg/utils/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ var MissingIeee8021xConfiguration = CustomError{Code: 117, Message: "MissingIeee
var SetMEBXPasswordFailed = CustomError{Code: 118, Message: "SetMEBXPasswordFailed"}
var ChangeAMTPasswordFailed = CustomError{Code: 119, Message: "ChangeAMTPasswordFailed"}
var UnableToConfigure = CustomError{Code: 120, Message: "UnableToConfigure"}
var ActivationFailedDecode64 = CustomError{Code: 121, Message: "ActivationFailed", Details: "failed to decode the certificate from Base64 format"}
var ActivationFailedWrongCertPass = CustomError{Code: 122, Message: "ActivationFailed", Details: "provisioning cert password incorrect"}
var ActivationFailedInvalidProvCert = CustomError{Code: 123, Message: "ActivationFailed", Details: "invalid provisioning certificate"}
var ActivationFailedNoCertFound = CustomError{Code: 124, Message: "ActivationFailed", Details: "no certificates found"}
var ActivationFailedNoPrivKeys = CustomError{Code: 125, Message: "ActivationFailed", Details: "no private keys found"}
var ActivationFailedNoRootCertFound = CustomError{Code: 126, Message: "ActivationFailed", Details: "root certificate not found in the pfx"}
var ActivationFailedGetCertHash = CustomError{Code: 127, Message: "ActivationFailed", Details: "failed to get certificate hashes"}
var ActivationFailedProvCertNoMatch = CustomError{Code: 128, Message: "ActivationFailed", Details: "the root of the provisioning certificate does not match any of the trusted roots in AMT"}
var ActivationFailedGeneralSettings = CustomError{Code: 129, Message: "ActivationFailed", Details: "wsman message error, failed to get general settings"}
var ActivationFailedSetupService = CustomError{Code: 130, Message: "ActivationFailed", Details: "wsman message error, failed to get host based setup service response"}
var ActivationFailedAddCert = CustomError{Code: 131, Message: "ActivationFailed", Details: "wsman message error, failed to add certificate to AMT"}
var ActivationFailedGenerateNonce = CustomError{Code: 132, Message: "ActivationFailed", Details: "failed to generate nonce"}
var ActivationFailedSignString = CustomError{Code: 133, Message: "ActivationFailed", Details: "failed to create signed string"}
var ActivationFailedGetControlMode = CustomError{Code: 134, Message: "ActivationFailed", Details: "failed to get control mode"}
var ActivationFailedControlMode = CustomError{Code: 135, Message: "ActivationFailed", Details: "recieved invalid control mode"}

// (150-199) Maintenance Errors
var SyncClockFailed = CustomError{Code: 150, Message: "SyncClockFailed"}
Expand Down
7 changes: 6 additions & 1 deletion pkg/utils/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ import "fmt"
type CustomError struct {
Code int
Message string
Details string
}

// Error implements the error interface for CustomError.
func (e CustomError) Error() string {
return fmt.Sprintf("Error %d: %s", e.Code, e.Message)
if e.Details != "" {
return fmt.Sprintf("Error %d: %s - Details: %s", e.Code, e.Message, e.Details)
} else {
return fmt.Sprintf("Error %d: %s", e.Code, e.Message)
}
}
Loading