|
1 | 1 | /* |
2 | | - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
28 | 28 | import java.io.ByteArrayOutputStream; |
29 | 29 | import java.io.IOException; |
30 | 30 | import java.io.Reader; |
| 31 | +import java.nio.charset.Charset; |
31 | 32 | import java.text.Normalizer; |
32 | 33 | import java.util.*; |
33 | 34 |
|
| 35 | +import static java.nio.charset.StandardCharsets.ISO_8859_1; |
34 | 36 | import static java.nio.charset.StandardCharsets.UTF_8; |
| 37 | +import static java.nio.charset.StandardCharsets.UTF_16BE; |
35 | 38 |
|
36 | 39 | import sun.security.util.*; |
37 | 40 | import sun.security.pkcs.PKCS9Attribute; |
@@ -589,6 +592,10 @@ private static boolean trailingSpace(Reader in) throws IOException { |
589 | 592 | throw new IOException("AVA, extra bytes = " |
590 | 593 | + derval.data.available()); |
591 | 594 | } |
| 595 | + |
| 596 | + if (value.tag == DerValue.tag_BMPString) { |
| 597 | + value.validateBMPString(); |
| 598 | + } |
592 | 599 | } |
593 | 600 |
|
594 | 601 | AVA(DerInputStream in) throws IOException { |
@@ -713,7 +720,8 @@ public String toRFC2253String(Map<String, String> oidMap) { |
713 | 720 | * NOTE: this implementation only emits DirectoryStrings of the |
714 | 721 | * types returned by isDerString(). |
715 | 722 | */ |
716 | | - String valStr = new String(value.getDataBytes(), UTF_8); |
| 723 | + String valStr = |
| 724 | + new String(value.getDataBytes(), getCharset(value, false)); |
717 | 725 |
|
718 | 726 | /* |
719 | 727 | * 2.4 (cont): If the UTF-8 string does not have any of the |
@@ -832,7 +840,8 @@ public String toRFC2253CanonicalString() { |
832 | 840 | * NOTE: this implementation only emits DirectoryStrings of the |
833 | 841 | * types returned by isDerString(). |
834 | 842 | */ |
835 | | - String valStr = new String(value.getDataBytes(), UTF_8); |
| 843 | + String valStr = |
| 844 | + new String(value.getDataBytes(), getCharset(value, true)); |
836 | 845 |
|
837 | 846 | /* |
838 | 847 | * 2.4 (cont): If the UTF-8 string does not have any of the |
@@ -927,6 +936,39 @@ private static boolean isDerString(DerValue value, boolean canonical) { |
927 | 936 | } |
928 | 937 | } |
929 | 938 |
|
| 939 | + /* |
| 940 | + * Returns the charset that should be used to decode each DN string type. |
| 941 | + * |
| 942 | + * This method ensures that multi-byte (UTF8String and BMPString) types |
| 943 | + * are decoded using the correct charset and the String forms represent |
| 944 | + * the correct characters. For 8-bit ASCII-based types (PrintableString |
| 945 | + * and IA5String), we return ISO_8859_1 rather than ASCII, so that the |
| 946 | + * complete range of characters can be represented, as many certificates |
| 947 | + * do not comply with the Internationalized Domain Name ACE format. |
| 948 | + * |
| 949 | + * NOTE: this method only supports DirectoryStrings of the types returned |
| 950 | + * by isDerString(). |
| 951 | + */ |
| 952 | + private static Charset getCharset(DerValue value, boolean canonical) { |
| 953 | + if (canonical) { |
| 954 | + return switch (value.tag) { |
| 955 | + case DerValue.tag_PrintableString -> ISO_8859_1; |
| 956 | + case DerValue.tag_UTF8String -> UTF_8; |
| 957 | + default -> throw new Error("unexpected tag: " + value.tag); |
| 958 | + }; |
| 959 | + } |
| 960 | + |
| 961 | + return switch (value.tag) { |
| 962 | + case DerValue.tag_PrintableString, |
| 963 | + DerValue.tag_T61String, |
| 964 | + DerValue.tag_IA5String, |
| 965 | + DerValue.tag_GeneralString -> ISO_8859_1; |
| 966 | + case DerValue.tag_BMPString -> UTF_16BE; |
| 967 | + case DerValue.tag_UTF8String -> UTF_8; |
| 968 | + default -> throw new Error("unexpected tag: " + value.tag); |
| 969 | + }; |
| 970 | + } |
| 971 | + |
930 | 972 | boolean hasRFC2253Keyword() { |
931 | 973 | return AVAKeyword.hasKeyword(oid, RFC2253); |
932 | 974 | } |
|
0 commit comments