|
1 | 1 | /* |
2 | | - * Copyright (c) 1996, 2011, 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 |
|
30 | 30 | import java.io.OutputStream; |
31 | 31 | import java.io.Reader; |
32 | 32 | import java.security.AccessController; |
| 33 | +import java.nio.charset.Charset; |
33 | 34 | import java.text.Normalizer; |
34 | 35 | import java.util.*; |
35 | 36 |
|
| 37 | +import static java.nio.charset.StandardCharsets.ISO_8859_1; |
| 38 | +import static java.nio.charset.StandardCharsets.UTF_8; |
| 39 | +import static java.nio.charset.StandardCharsets.UTF_16BE; |
| 40 | + |
36 | 41 | import sun.security.action.GetBooleanAction; |
37 | 42 | import sun.security.util.*; |
38 | 43 | import sun.security.pkcs.PKCS9Attribute; |
@@ -606,6 +611,10 @@ private static boolean trailingSpace(Reader in) throws IOException { |
606 | 611 | throw new IOException("AVA, extra bytes = " |
607 | 612 | + derval.data.available()); |
608 | 613 | } |
| 614 | + |
| 615 | + if (value.tag == DerValue.tag_BMPString) { |
| 616 | + value.validateBMPString(); |
| 617 | + } |
609 | 618 | } |
610 | 619 |
|
611 | 620 | AVA(DerInputStream in) throws IOException { |
@@ -753,7 +762,7 @@ public String toRFC2253String(Map<String, String> oidMap) { |
753 | 762 | */ |
754 | 763 | String valStr = null; |
755 | 764 | try { |
756 | | - valStr = new String(value.getDataBytes(), "UTF8"); |
| 765 | + valStr = new String(value.getDataBytes(), getCharset(value, false)); |
757 | 766 | } catch (IOException ie) { |
758 | 767 | throw new IllegalArgumentException("DER Value conversion"); |
759 | 768 | } |
@@ -906,7 +915,7 @@ public String toRFC2253CanonicalString() { |
906 | 915 | */ |
907 | 916 | String valStr = null; |
908 | 917 | try { |
909 | | - valStr = new String(value.getDataBytes(), "UTF8"); |
| 918 | + valStr = new String(value.getDataBytes(), getCharset(value, true)); |
910 | 919 | } catch (IOException ie) { |
911 | 920 | throw new IllegalArgumentException("DER Value conversion"); |
912 | 921 | } |
@@ -1026,6 +1035,46 @@ private static boolean isDerString(DerValue value, boolean canonical) { |
1026 | 1035 | } |
1027 | 1036 | } |
1028 | 1037 |
|
| 1038 | + /* |
| 1039 | + * Returns the charset that should be used to decode each DN string type. |
| 1040 | + * |
| 1041 | + * This method ensures that multi-byte (UTF8String and BMPString) types |
| 1042 | + * are decoded using the correct charset and the String forms represent |
| 1043 | + * the correct characters. For 8-bit ASCII-based types (PrintableString |
| 1044 | + * and IA5String), we return ISO_8859_1 rather than ASCII, so that the |
| 1045 | + * complete range of characters can be represented, as many certificates |
| 1046 | + * do not comply with the Internationalized Domain Name ACE format. |
| 1047 | + * |
| 1048 | + * NOTE: this method only supports DirectoryStrings of the types returned |
| 1049 | + * by isDerString(). |
| 1050 | + */ |
| 1051 | + private static Charset getCharset(DerValue value, boolean canonical) { |
| 1052 | + if (canonical) { |
| 1053 | + switch (value.tag) { |
| 1054 | + case DerValue.tag_PrintableString: |
| 1055 | + return ISO_8859_1; |
| 1056 | + case DerValue.tag_UTF8String: |
| 1057 | + return UTF_8; |
| 1058 | + default: |
| 1059 | + throw new Error("unexpected tag: " + value.tag); |
| 1060 | + } |
| 1061 | + } |
| 1062 | + |
| 1063 | + switch (value.tag) { |
| 1064 | + case DerValue.tag_PrintableString: |
| 1065 | + case DerValue.tag_T61String: |
| 1066 | + case DerValue.tag_IA5String: |
| 1067 | + case DerValue.tag_GeneralString: |
| 1068 | + return ISO_8859_1; |
| 1069 | + case DerValue.tag_BMPString: |
| 1070 | + return UTF_16BE; |
| 1071 | + case DerValue.tag_UTF8String: |
| 1072 | + return UTF_8; |
| 1073 | + default: |
| 1074 | + throw new Error("unexpected tag: " + value.tag); |
| 1075 | + } |
| 1076 | + } |
| 1077 | + |
1029 | 1078 | boolean hasRFC2253Keyword() { |
1030 | 1079 | return AVAKeyword.hasKeyword(oid, RFC2253); |
1031 | 1080 | } |
|
0 commit comments