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
- Check the certificate's key algorithm; if it is ECC, extend the code to use x509.ParsePKIXPublicKey instead.
- Reconfigure the RDP server to use an RSA certificate (standard for RDP).
- Log the wrapped error to distinguish malformed data from wrong-algorithm data.
- 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
- Ensure RDP hosts use RSA certificates (the RDP default).
- Reject/flag ECC-cert hosts during discovery.
- Extend parsing with x509.ParsePKIXPublicKey if non-RSA support is needed.
- Log the wrapped error to separate malformed-bitstring from wrong-algorithm cases.
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
- parse certificate: %w
- unmarshal public key info: %w
- unsupported public key type: %T
- empty certificate chain
- Unhandled saveSessionInfo type 0x%x
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/d2a3a9c5c1fb15ea.
Report an issue: GitHub.