{"record":{"id":"d2a3a9c5c1fb15ea","repo":"shadow1ng/fscan","slug":"parse-pkcs1-public-key-w","errorCode":null,"errorMessage":"parse PKCS1 public key: %w","messagePattern":"parse PKCS1 public key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/grdp/protocol/t125/gcc/gcc.go","lineNumber":428,"sourceCode":"\t\treturn nil, errors.New(\"empty certificate chain\")\n\t}\n\tdata := x.CertBlobArray[len(x.CertBlobArray)-1].AbCert\n\tcert, err := x509.ParseCertificate(data)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse certificate: %w\", err)\n\t}\n\tif cert.PublicKey == nil {\n\t\tvar pubKeyInfo struct {\n\t\t\tAlgorithm        pkix.AlgorithmIdentifier\n\t\t\tSubjectPublicKey asn1.BitString\n\t\t}\n\t\t_, err = asn1.Unmarshal(cert.RawSubjectPublicKeyInfo, &pubKeyInfo)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unmarshal public key info: %w\", err)\n\t\t}\n\t\trsaPublicKey, err := x509.ParsePKCS1PublicKey(pubKeyInfo.SubjectPublicKey.Bytes)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"parse PKCS1 public key: %w\", err)\n\t\t}\n\t\treturn rsaPublicKey, nil\n\t}\n\trsaPublicKey, ok := cert.PublicKey.(*rsa.PublicKey)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unsupported public key type: %T\", cert.PublicKey)\n\t}\n\treturn rsaPublicKey, nil\n}\nfunc (x *X509CertificateChain) Verify() bool {\n\treturn true\n}\nfunc (x *X509CertificateChain) Encrypt() []byte {\n\t//todo\n\treturn nil\n}\nfunc (x *X509CertificateChain) Unpack(r io.Reader) error {\n\treturn struc.Unpack(r, x)","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/libs/grdp/protocol/t125/gcc/gcc.go#L410-L446","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nrsaPublicKey, err := x509.ParsePKCS1PublicKey(pubKeyInfo.SubjectPublicKey.Bytes)\n// after\nanyKey, err := x509.ParsePKIXPublicKey(pubKeyInfo.SubjectPublicKey.FullBytes)\nif err != nil { return nil, err }\nrsaPublicKey, ok := anyKey.(*rsa.PublicKey)\nif !ok { return nil, fmt.Errorf(\"non-RSA key: %T\", anyKey) }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isRSAKey(pub interface{ Equal(crypto.PublicKey) bool }) bool {\n\trsaKey, ok := any(pub).(*rsa.PublicKey)\n\treturn ok && rsaKey.N.BitLen() >= 2048\n}","tryCatchPattern":"pub, err := certChain.PublicKey()\nif err != nil && strings.Contains(err.Error(), \"parse PKCS1 public key:\") {\n\treturn fmt.Errorf(\"server key is not RSA; grdp requires RSA server certificates: %w\", err)\n}","preventionTips":["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."],"tags":["rsa","x509","parsing","rdp"],"backgroundTag":"schema-validation-failed","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}