-
Notifications
You must be signed in to change notification settings - Fork 24
fix: resolve local LMS enforcement issue for AMT19 above #1257
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
| package certs | ||
|
|
||
| import ( | ||
| "bytes" | ||
| "crypto/sha256" | ||
| "crypto/tls" | ||
| "crypto/x509" | ||
|
|
@@ -18,11 +19,14 @@ import ( | |
|
|
||
| // generates a TLS configuration based on the provided mode. | ||
| func GetTLSConfig(mode *int, amtCertInfo *amt.SecureHBasedResponse, skipAMTCertCheck bool) *tls.Config { | ||
| tlsConfig := &tls.Config{} | ||
|
|
||
| tlsConfig.InsecureSkipVerify = skipAMTCertCheck | ||
| tlsConfig := &tls.Config{ | ||
| InsecureSkipVerify: skipAMTCertCheck, | ||
| } | ||
|
|
||
| if *mode == 0 { // pre-provisioning mode | ||
| // Pre-provisioning uses AMT loopback/self-signed TLS; allow handshake and | ||
| // enforce certificate validation in VerifyPeerCertificate. | ||
| tlsConfig.InsecureSkipVerify = true | ||
| tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { | ||
| if skipAMTCertCheck { | ||
| return nil | ||
|
|
@@ -32,7 +36,11 @@ func GetTLSConfig(mode *int, amtCertInfo *amt.SecureHBasedResponse, skipAMTCertC | |
| } | ||
| } else { | ||
| // default tls config if device is in ACM or CCM | ||
| log.Trace("Setting default TLS Config for ACM/CCM mode") | ||
| if skipAMTCertCheck { | ||
| log.Trace("Skipping AMT certificate verification for ACM/CCM mode (loopback TLS)") | ||
| } else { | ||
| log.Trace("Using default TLS config for ACM/CCM mode") | ||
| } | ||
| } | ||
|
|
||
| return tlsConfig | ||
|
|
@@ -62,7 +70,7 @@ func VerifyCertificates(rawCerts [][]byte, mode *int, amtCertInfo *amt.SecureHBa | |
| return err | ||
| } | ||
|
|
||
| log.Infof("Cert[%d]: Subject=%s, Issuer=%s, EKU=%v", i, cert.Subject, cert.Issuer, cert.ExtKeyUsage) | ||
| log.Tracef("Cert[%d]: Subject=%s, Issuer=%s, EKU=%v", i, cert.Subject, cert.Issuer, cert.ExtKeyUsage) | ||
|
|
||
| parsedCerts = append(parsedCerts, cert) | ||
|
|
||
|
|
@@ -84,6 +92,31 @@ func VerifyCertificates(rawCerts [][]byte, mode *int, amtCertInfo *amt.SecureHBa | |
|
|
||
| return nil | ||
| case selfSignedChainLength: | ||
| // On AMT 19+ loopback TLS, the LMS/AMT certificate is typically a single | ||
| // self-signed certificate that is not rooted in the system trust store. | ||
| // In pre-provisioning mode (mode == 0), accept this only when the leaf | ||
| // certificate matches AMT loopback expectations. | ||
| if mode != nil && *mode == 0 { | ||
| cert, err := x509.ParseCertificate(rawCerts[0]) | ||
| if err != nil { | ||
| log.Error("Failed to parse self-signed AMT loopback certificate:", err) | ||
|
|
||
| return err | ||
| } | ||
|
|
||
| if !bytes.Equal(cert.RawSubject, cert.RawIssuer) { | ||
| return errors.New("single AMT loopback certificate is not self-signed") | ||
| } | ||
|
Comment on lines
+106
to
+109
|
||
|
|
||
| if err := VerifyLeafCertificate(cert, amtCertInfo); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| log.Trace("Accepting self-signed AMT loopback certificate in pre-provisioning mode") | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| return HandleAMTTransition(mode) | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -258,6 +258,9 @@ func (cmd *ActivateCmd) Run(ctx *commands.Context) error { | |||||||||||
|
|
||||||||||||
| // runRemoteActivation executes remote activation using the remote service | ||||||||||||
| func (cmd *ActivateCmd) runRemoteActivation(ctx *commands.Context) error { | ||||||||||||
| // Propagate local TLS enforcement status detected in AMTBaseCmd.AfterApply | ||||||||||||
| ctx.LocalTLSEnforced = cmd.LocalTLSEnforced | ||||||||||||
|
Comment on lines
+261
to
+262
|
||||||||||||
| // Propagate local TLS enforcement status detected in AMTBaseCmd.AfterApply | |
| ctx.LocalTLSEnforced = cmd.LocalTLSEnforced | |
| // Propagate activation state detected in AMTBaseCmd.AfterApply | |
| ctx.LocalTLSEnforced = cmd.LocalTLSEnforced | |
| ctx.ControlMode = cmd.GetControlMode() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -169,6 +169,7 @@ func (service *RemoteActivationService) requestActivation(deviceInfo map[string] | |
| Verbose: service.context.Verbose, | ||
| SkipCertCheck: service.context.SkipCertCheck, | ||
| SkipAmtCertCheck: service.context.SkipAMTCertCheck, | ||
| LocalTLSEnforced: service.context.LocalTLSEnforced, | ||
| ControlMode: service.context.ControlMode, | ||
|
Comment on lines
169
to
173
|
||
| TenantID: service.context.TenantID, | ||
| Password: service.context.AMTPassword, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -130,6 +130,7 @@ func (cmd *DeactivateCmd) executeRemoteDeactivate(ctx *Context) error { | |||||||
| Verbose: ctx.Verbose, | ||||||||
| SkipCertCheck: ctx.SkipCertCheck, | ||||||||
| SkipAmtCertCheck: ctx.SkipAMTCertCheck, | ||||||||
| LocalTLSEnforced: cmd.LocalTLSEnforced, | ||||||||
|
||||||||
| LocalTLSEnforced: cmd.LocalTLSEnforced, | |
| LocalTLSEnforced: cmd.LocalTLSEnforced, | |
| ControlMode: cmd.GetControlMode(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In GetTLSConfig(), the ACM/CCM branch leaves default TLS verification enabled (InsecureSkipVerify stays false when skipAMTCertCheck is false) and does not set VerifyPeerCertificate. For AMT 19+ loopback TLS where LMS presents a self-signed/untrusted certificate, this will still fail the handshake. Consider always enabling InsecureSkipVerify for loopback and performing certificate validation via VerifyPeerCertificate/VerifyCertificates for all modes when skipAMTCertCheck is false.