|
1 | 1 | /* |
2 | | - * Copyright (c) 1996, 2022, 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.action.GetBooleanAction; |
37 | 40 | import sun.security.util.*; |
@@ -590,6 +593,10 @@ private static boolean trailingSpace(Reader in) throws IOException { |
590 | 593 | throw new IOException("AVA, extra bytes = " |
591 | 594 | + derval.data.available()); |
592 | 595 | } |
| 596 | + |
| 597 | + if (value.tag == DerValue.tag_BMPString) { |
| 598 | + value.validateBMPString(); |
| 599 | + } |
593 | 600 | } |
594 | 601 |
|
595 | 602 | AVA(DerInputStream in) throws IOException { |
@@ -714,7 +721,8 @@ public String toRFC2253String(Map<String, String> oidMap) { |
714 | 721 | * NOTE: this implementation only emits DirectoryStrings of the |
715 | 722 | * types returned by isDerString(). |
716 | 723 | */ |
717 | | - String valStr = new String(value.getDataBytes(), UTF_8); |
| 724 | + String valStr = |
| 725 | + new String(value.getDataBytes(), getCharset(value, false)); |
718 | 726 |
|
719 | 727 | /* |
720 | 728 | * 2.4 (cont): If the UTF-8 string does not have any of the |
@@ -839,7 +847,8 @@ public String toRFC2253CanonicalString() { |
839 | 847 | * NOTE: this implementation only emits DirectoryStrings of the |
840 | 848 | * types returned by isDerString(). |
841 | 849 | */ |
842 | | - String valStr = new String(value.getDataBytes(), UTF_8); |
| 850 | + String valStr = |
| 851 | + new String(value.getDataBytes(), getCharset(value, true)); |
843 | 852 |
|
844 | 853 | /* |
845 | 854 | * 2.4 (cont): If the UTF-8 string does not have any of the |
@@ -942,6 +951,39 @@ private static boolean isDerString(DerValue value, boolean canonical) { |
942 | 951 | } |
943 | 952 | } |
944 | 953 |
|
| 954 | + /* |
| 955 | + * Returns the charset that should be used to decode each DN string type. |
| 956 | + * |
| 957 | + * This method ensures that multi-byte (UTF8String and BMPString) types |
| 958 | + * are decoded using the correct charset and the String forms represent |
| 959 | + * the correct characters. For 8-bit ASCII-based types (PrintableString |
| 960 | + * and IA5String), we return ISO_8859_1 rather than ASCII, so that the |
| 961 | + * complete range of characters can be represented, as many certificates |
| 962 | + * do not comply with the Internationalized Domain Name ACE format. |
| 963 | + * |
| 964 | + * NOTE: this method only supports DirectoryStrings of the types returned |
| 965 | + * by isDerString(). |
| 966 | + */ |
| 967 | + private static Charset getCharset(DerValue value, boolean canonical) { |
| 968 | + if (canonical) { |
| 969 | + return switch (value.tag) { |
| 970 | + case DerValue.tag_PrintableString -> ISO_8859_1; |
| 971 | + case DerValue.tag_UTF8String -> UTF_8; |
| 972 | + default -> throw new Error("unexpected tag: " + value.tag); |
| 973 | + }; |
| 974 | + } |
| 975 | + |
| 976 | + return switch (value.tag) { |
| 977 | + case DerValue.tag_PrintableString, |
| 978 | + DerValue.tag_T61String, |
| 979 | + DerValue.tag_IA5String, |
| 980 | + DerValue.tag_GeneralString -> ISO_8859_1; |
| 981 | + case DerValue.tag_BMPString -> UTF_16BE; |
| 982 | + case DerValue.tag_UTF8String -> UTF_8; |
| 983 | + default -> throw new Error("unexpected tag: " + value.tag); |
| 984 | + }; |
| 985 | + } |
| 986 | + |
945 | 987 | boolean hasRFC2253Keyword() { |
946 | 988 | return AVAKeyword.hasKeyword(oid, RFC2253); |
947 | 989 | } |
|
0 commit comments