shadow1ng/fscan · error

unmarshal public key info: %w

Error message

unmarshal public key info: %w

What it means

This fallback path runs when cert.PublicKey is nil. The library re-parses the certificate's RawSubjectPublicKeyInfo via asn1.Unmarshal into an algorithm/bitstring struct; if that ASN.1 decode fails, it returns 'unmarshal public key info: %w'.

Source

Thrown at libs/grdp/protocol/t125/gcc/gcc.go:424

}

func (x *X509CertificateChain) GetPublicKey() (*rsa.PublicKey, error) {
	if len(x.CertBlobArray) == 0 {
		return nil, errors.New("empty certificate chain")
	}
	data := x.CertBlobArray[len(x.CertBlobArray)-1].AbCert
	cert, err := x509.ParseCertificate(data)
	if err != nil {
		return nil, fmt.Errorf("parse certificate: %w", err)
	}
	if cert.PublicKey == nil {
		var pubKeyInfo struct {
			Algorithm        pkix.AlgorithmIdentifier
			SubjectPublicKey asn1.BitString
		}
		_, err = asn1.Unmarshal(cert.RawSubjectPublicKeyInfo, &pubKeyInfo)
		if err != nil {
			return nil, fmt.Errorf("unmarshal public key info: %w", err)
		}
		rsaPublicKey, err := x509.ParsePKCS1PublicKey(pubKeyInfo.SubjectPublicKey.Bytes)
		if err != nil {
			return nil, fmt.Errorf("parse PKCS1 public key: %w", err)
		}
		return rsaPublicKey, nil
	}
	rsaPublicKey, ok := cert.PublicKey.(*rsa.PublicKey)
	if !ok {
		return nil, fmt.Errorf("unsupported public key type: %T", cert.PublicKey)
	}
	return rsaPublicKey, nil
}
func (x *X509CertificateChain) Verify() bool {
	return true
}
func (x *X509CertificateChain) Encrypt() []byte {
	//todo

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Inspect the certificate with openssl: `openssl x509 -inform der -in cert.der -text` to see its SPKI algorithm.
  2. Confirm the SPKI is actually RSA; EC/other keys need different parsing (x509.ParsePKIXPublicKey).
  3. Update the Go toolchain — newer crypto/x509 versions handle more SPKI encodings.
  4. Regenerate/use a standard RSA server certificate on the RDP host if you control it.
Defensive patterns

Strategy: try-catch

Try / catch

pub, err := certChain.PublicKey()
if err != nil && strings.Contains(err.Error(), "unmarshal public key info:") {
	return fmt.Errorf("certificate SPKI not parseable by this Go version: %w", err)
}

Prevention

When it happens

Trigger: The parsed certificate has no PublicKey but its RawSubjectPublicKeyInfo bytes are malformed or in an algorithm/structure the struct does not match (e.g. unusual parameter encoding in AlgorithmIdentifier).

Common situations: Exotic or legacy RDP server certificates with unusual SPKI encodings; certificates using algorithms outside RSA that don't populate cert.PublicKey in the expected way after the initial parse.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/bf2caea58f3a3da1. Report an issue: GitHub.