shadow1ng/fscan · error
parse certificate: %w
Error message
parse certificate: %w
What it means
When extracting the server's public key from the X.509 certificate chain carried in the GCC data, x509.ParseCertificate failed on the last certificate blob (AbCert) of the chain. The library wraps the underlying ASN.1 parse error with 'parse certificate: %w'.
Source
Thrown at libs/grdp/protocol/t125/gcc/gcc.go:415
type CertBlob struct {
CbCert uint32 `struc:"little,sizeof=AbCert"`
AbCert []byte `struc:"little"`
}
type X509CertificateChain struct {
NumCertBlobs uint32 `struc:"little,sizeof=CertBlobArray"`
CertBlobArray []CertBlob `struc:"little"`
Padding []byte `struc:"[12]byte"`
}
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 {View on GitHub (pinned to 95cc12e753)
Solutions
- Hex-dump the AbCert blob and verify it starts with a DER SEQUENCE (0x30 0x82).
- Check the cert chain blob type; if the server sends PROPRIETARYCERT, this parser path does not apply.
- Update grdp to a version with broader server-certificate handling.
- Verify the ServerSecurityData/GCC parsing offsets are correct for this server's response.
Defensive patterns
Strategy: try-catch
Validate before calling
func looksLikeDER(b []byte) bool { return len(b) > 2 && b[0] == 0x30 }
if !looksLikeDER(certBlob) { return errors.New("cert blob is not DER X.509; likely proprietary cert type") } Try / catch
pub, err := certChain.PublicKey()
if err != nil && strings.Contains(err.Error(), "parse certificate:") {
return fmt.Errorf("server certificate unreadable (possibly proprietary cert format): %w", err)
} Prevention
- Check the server cert chain blob type before assuming X.509.
- Prefer NLA mode where server cert handling is TLS-based.
- Hex-dump AbCert blobs when debugging nonstandard servers.
- Keep grdp updated for proprietary-certificate handling.
When it happens
Trigger: The AbCert bytes from CertBlobArray are not a valid DER-encoded X.509 certificate — truncated data, proprietary (non-X.509) certificate format (e.g. PROPRIETARYCERT in the server cert chain), or a parser misalignment.
Common situations: Old/quirky RDP servers that use proprietary certificate types instead of X509_CERTIFICATE_CHAIN; MTU/truncation issues in handshake capture; grdp parser bugs on exotic server configs.
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.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- empty certificate chain
- unmarshal public key info: %w
- parse PKCS1 public key: %w
- failed to get server public key
- Unsupported version
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/00360091d5b28f8e.
Report an issue: GitHub.