{"record":{"id":"27bcd2fd4a2d48fd","repo":"elastic/elasticsearch","slug":"invalid-der-can-t-handle-ucs-4-string","errorCode":null,"errorMessage":"Invalid DER: can't handle UCS-4 string","messagePattern":"Invalid DER: can't handle UCS-4 string","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/DerParser.java","lineNumber":261,"sourceCode":"                case Type.PRINTABLE_STRING:\n                case Type.VIDEOTEX_STRING:\n                case Type.IA5_STRING:\n                case Type.GRAPHIC_STRING:\n                case Type.ISO646_STRING:\n                case Type.GENERAL_STRING:\n                    encoding = \"ISO-8859-1\"; //$NON-NLS-1$\n                    break;\n\n                case Type.BMP_STRING:\n                    encoding = \"UTF-16BE\"; //$NON-NLS-1$\n                    break;\n\n                case Type.UTF8_STRING:\n                    encoding = \"UTF-8\"; //$NON-NLS-1$\n                    break;\n\n                case Type.UNIVERSAL_STRING:\n                    throw new IOException(\"Invalid DER: can't handle UCS-4 string\"); //$NON-NLS-1$\n\n                default:\n                    throw new IOException(\"Invalid DER: object is not a string\"); //$NON-NLS-1$\n            }\n\n            return new String(value, encoding);\n        }\n\n        public String getOid() throws IOException {\n\n            if (type != Type.OBJECT_OID) {\n                throw new IOException(\"Ivalid DER: object is not object OID\");\n            }\n            StringBuilder sb = new StringBuilder(64);\n            switch (value[0] / 40) {\n                case 0 -> sb.append('0');\n                case 1 -> {\n                    sb.append('1');","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/DerParser.java#L243-L279","documentation":"Thrown by Asn1Object.getString() when the parsed element has tag Type.UNIVERSAL_STRING (0x1C). UNIVERSAL_STRING encodes characters in UCS-4 (UTF-32), which this minimal DerParser explicitly does not support. The error is a deliberate unsupported-format rejection, not corruption.","triggerScenarios":"getString() is called on an ASN.1 element whose type byte is 0x1C. In practice this path is reached when parsing the private-key field of an EC key (parseEcDer line 604 calls getString()) where the encoding of the key octet-string element unexpectedly uses a UCS-4 string tag — extremely rare and almost always indicates the parser is misaligned.","commonSituations":"Misaligned DER causing a non-string element to be interpreted as a string tag, or a key generated by a tool that emits non-standard ASN.1 string types for fields the parser expects as OCTET_STRING.","solutions":["Regenerate the key with a conformant tool (openssl) — UCS-4 UNIVERSAL_STRING is essentially never legitimate in private-key DER.","Verify parser alignment with `openssl asn1parse -inform DER -in key.der`.","Convert to PKCS#8 (`openssl pkcs8 -topk8`) so PemUtils uses the PKCS#8 path that does not call getString() on the private key.","If you genuinely need UCS-4 support, pre-convert the string externally before invoking this parser."],"exampleFix":"// before: EC key with non-standard encoding triggers UCS-4 path\nPrivateKey pk = PemUtils.parsePrivateKey(ecKeyPath, passwordSupplier);\n\n// after: re-encode to PKCS#8 which uses a different (OCTET STRING) field\n// openssl pkcs8 -topk8 -in ec.pem -out ec.pk8.pem\nPrivateKey pk = PemUtils.parsePrivateKey(pk8KeyPath, passwordSupplier);","handlingStrategy":"validation","validationCode":"public static void requireNotUniversalString(DerParser.Asn1Object o) {\n    if (o != null && o.getType() == DerParser.Type.UNIVERSAL_STRING) {\n        throw new IllegalArgumentException(\"UNIVERSAL_STRING (UCS-4) is not supported; re-encode the key\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use PKCS#8-encoded keys, which use OCTET_STRING rather than UNIVERSAL_STRING for private-key material.","Regenerate keys with conformant tooling (openssl).","Validate ASN.1 schema with `openssl asn1parse` before parsing."],"tags":["ssl","der","asn1","keystore","elasticsearch","crypto"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}