shadow1ng/fscan · error

parse PKCS1 public key: %w

Error message

parse PKCS1 public key: %w

What it means

After unmarshalling the SPKI, the library parses the embedded subjectPublicKey bytes as a PKCS#1 RSA public key. If ParsePKCS1PublicKey fails, it returns 'parse PKCS1 public key: %w', meaning the key bits are not a valid RSA modulus/exponent pair.

Source

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

		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
	return nil
}
func (x *X509CertificateChain) Unpack(r io.Reader) error {
	return struc.Unpack(r, x)

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Check the certificate's key algorithm; if it is ECC, extend the code to use x509.ParsePKIXPublicKey instead.
  2. Reconfigure the RDP server to use an RSA certificate (standard for RDP).
  3. Log the wrapped error to distinguish malformed data from wrong-algorithm data.
  4. Update grdp/Go version to get broader key-format support.

Example fix

// before
rsaPublicKey, err := x509.ParsePKCS1PublicKey(pubKeyInfo.SubjectPublicKey.Bytes)
// after
anyKey, err := x509.ParsePKIXPublicKey(pubKeyInfo.SubjectPublicKey.FullBytes)
if err != nil { return nil, err }
rsaPublicKey, ok := anyKey.(*rsa.PublicKey)
if !ok { return nil, fmt.Errorf("non-RSA key: %T", anyKey) }
Defensive patterns

Strategy: type-guard

Type guard

func isRSAKey(pub interface{ Equal(crypto.PublicKey) bool }) bool {
	rsaKey, ok := any(pub).(*rsa.PublicKey)
	return ok && rsaKey.N.BitLen() >= 2048
}

Try / catch

pub, err := certChain.PublicKey()
if err != nil && strings.Contains(err.Error(), "parse PKCS1 public key:") {
	return fmt.Errorf("server key is not RSA; grdp requires RSA server certificates: %w", err)
}

Prevention

When it happens

Trigger: The SPKI declares or contains a non-RSA key (e.g. EC or DSA key bytes) or the SPKI bit string was corrupted/misparsed, so the bytes fail RSA PKCS#1 validation.

Common situations: RDP hosts configured with ECC certificates; certificates with unusual key sizes; grdp assuming RSA-only server certificates on servers that no longer default to RSA.

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/d2a3a9c5c1fb15ea. Report an issue: GitHub.