Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/x509/DNSName.java
38831 views
1
/*
2
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.security.x509;
27
28
import java.io.IOException;
29
import java.util.Locale;
30
31
import sun.security.util.*;
32
33
/**
34
* This class implements the DNSName as required by the GeneralNames
35
* ASN.1 object.
36
* <p>
37
* [RFC5280] When the subjectAltName extension contains a domain name system
38
* label, the domain name MUST be stored in the dNSName (an IA5String).
39
* The name MUST be in the "preferred name syntax", as specified by
40
* Section 3.5 of [RFC1034] and as modified by Section 2.1 of
41
* [RFC1123]. Note that while uppercase and lowercase letters are
42
* allowed in domain names, no significance is attached to the case. In
43
* addition, while the string " " is a legal domain name, subjectAltName
44
* extensions with a dNSName of " " MUST NOT be used. Finally, the use
45
* of the DNS representation for Internet mail addresses
46
* (subscriber.example.com instead of [email protected]) MUST NOT
47
* be used; such identities are to be encoded as rfc822Name.
48
* <p>
49
* @author Amit Kapoor
50
* @author Hemma Prafullchandra
51
*/
52
public class DNSName implements GeneralNameInterface {
53
private String name;
54
55
private static final String alphaDigits =
56
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
57
58
/**
59
* Create the DNSName object from the passed encoded Der value.
60
*
61
* @param derValue the encoded DER DNSName.
62
* @exception IOException on error.
63
*/
64
public DNSName(DerValue derValue) throws IOException {
65
name = derValue.getIA5String();
66
}
67
68
/**
69
* Create the DNSName object with the specified name.
70
*
71
* @param name the DNSName.
72
* @throws IOException if the name is not a valid DNSName subjectAltName
73
*/
74
public DNSName(String name) throws IOException {
75
if (name == null || name.length() == 0)
76
throw new IOException("DNSName must not be null or empty");
77
if (name.contains(" "))
78
throw new IOException("DNSName with blank components is not permitted");
79
if (name.startsWith(".") || name.endsWith("."))
80
throw new IOException("DNSName may not begin or end with a .");
81
/*
82
* Name will consist of label components separated by "."
83
* startIndex is the index of the first character of a component
84
* endIndex is the index of the last character of a component plus 1
85
*/
86
for (int endIndex,startIndex = 0; startIndex < name.length(); startIndex = endIndex+1) {
87
endIndex = name.indexOf('.', startIndex);
88
if (endIndex < 0) {
89
endIndex = name.length();
90
}
91
if (endIndex - startIndex < 1)
92
throw new IOException("DNSName with empty components are not permitted");
93
94
// RFC 1123: DNSName components must begin with a letter or digit
95
if (alphaDigits.indexOf(name.charAt(startIndex)) < 0)
96
throw new IOException("DNSName components must begin with a letter or digit");
97
//nonStartIndex: index for characters in the component beyond the first one
98
for (int nonStartIndex=startIndex+1; nonStartIndex < endIndex; nonStartIndex++) {
99
char x = name.charAt(nonStartIndex);
100
if ((alphaDigits).indexOf(x) < 0 && x != '-')
101
throw new IOException("DNSName components must consist of letters, digits, and hyphens");
102
}
103
}
104
this.name = name;
105
}
106
107
108
/**
109
* Return the type of the GeneralName.
110
*/
111
public int getType() {
112
return (GeneralNameInterface.NAME_DNS);
113
}
114
115
/**
116
* Return the actual name value of the GeneralName.
117
*/
118
public String getName() {
119
return name;
120
}
121
122
/**
123
* Encode the DNSName into the DerOutputStream.
124
*
125
* @param out the DER stream to encode the DNSName to.
126
* @exception IOException on encoding errors.
127
*/
128
public void encode(DerOutputStream out) throws IOException {
129
out.putIA5String(name);
130
}
131
132
/**
133
* Convert the name into user readable string.
134
*/
135
public String toString() {
136
return ("DNSName: " + name);
137
}
138
139
/**
140
* Compares this name with another, for equality.
141
*
142
* @return true iff the names are equivalent
143
* according to RFC5280.
144
*/
145
public boolean equals(Object obj) {
146
if (this == obj)
147
return true;
148
149
if (!(obj instanceof DNSName))
150
return false;
151
152
DNSName other = (DNSName)obj;
153
154
// RFC5280 mandates that these names are
155
// not case-sensitive
156
return name.equalsIgnoreCase(other.name);
157
}
158
159
/**
160
* Returns the hash code value for this object.
161
*
162
* @return a hash code value for this object.
163
*/
164
public int hashCode() {
165
return name.toUpperCase(Locale.ENGLISH).hashCode();
166
}
167
168
/**
169
* Return type of constraint inputName places on this name:<ul>
170
* <li>NAME_DIFF_TYPE = -1: input name is different type from name (i.e. does not constrain).
171
* <li>NAME_MATCH = 0: input name matches name.
172
* <li>NAME_NARROWS = 1: input name narrows name (is lower in the naming subtree)
173
* <li>NAME_WIDENS = 2: input name widens name (is higher in the naming subtree)
174
* <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but is same type.
175
* </ul>. These results are used in checking NameConstraints during
176
* certification path verification.
177
* <p>
178
* RFC5280: DNS name restrictions are expressed as host.example.com.
179
* Any DNS name that can be constructed by simply adding zero or more
180
* labels to the left-hand side of the name satisfies the name constraint.
181
* For example, www.host.example.com would satisfy the constraint but
182
* host1.example.com would not.
183
* <p>
184
* draft-ietf-pkix-new-part1-00.txt: DNSName restrictions are expressed as foo.bar.com.
185
* Any DNSName that
186
* can be constructed by simply adding to the left hand side of the name
187
* satisfies the name constraint. For example, www.foo.bar.com would
188
* satisfy the constraint but foo1.bar.com would not.
189
* <p>
190
* RFC1034: By convention, domain names can be stored with arbitrary case, but
191
* domain name comparisons for all present domain functions are done in a
192
* case-insensitive manner, assuming an ASCII character set, and a high
193
* order zero bit.
194
* <p>
195
* @param inputName to be checked for being constrained
196
* @returns constraint type above
197
* @throws UnsupportedOperationException if name is not exact match, but narrowing and widening are
198
* not supported for this name type.
199
*/
200
public int constrains(GeneralNameInterface inputName) throws UnsupportedOperationException {
201
int constraintType;
202
if (inputName == null)
203
constraintType = NAME_DIFF_TYPE;
204
else if (inputName.getType() != NAME_DNS)
205
constraintType = NAME_DIFF_TYPE;
206
else {
207
String inName =
208
(((DNSName)inputName).getName()).toLowerCase(Locale.ENGLISH);
209
String thisName = name.toLowerCase(Locale.ENGLISH);
210
if (inName.equals(thisName))
211
constraintType = NAME_MATCH;
212
else if (thisName.endsWith(inName)) {
213
int inNdx = thisName.lastIndexOf(inName);
214
if (thisName.charAt(inNdx-1) == '.' )
215
constraintType = NAME_WIDENS;
216
else
217
constraintType = NAME_SAME_TYPE;
218
} else if (inName.endsWith(thisName)) {
219
int ndx = inName.lastIndexOf(thisName);
220
if (inName.charAt(ndx-1) == '.' )
221
constraintType = NAME_NARROWS;
222
else
223
constraintType = NAME_SAME_TYPE;
224
} else {
225
constraintType = NAME_SAME_TYPE;
226
}
227
}
228
return constraintType;
229
}
230
231
/**
232
* Return subtree depth of this name for purposes of determining
233
* NameConstraints minimum and maximum bounds and for calculating
234
* path lengths in name subtrees.
235
*
236
* @returns distance of name from root
237
* @throws UnsupportedOperationException if not supported for this name type
238
*/
239
public int subtreeDepth() throws UnsupportedOperationException {
240
// subtree depth is always at least 1
241
int sum = 1;
242
243
// count dots
244
for (int i = name.indexOf('.'); i >= 0; i = name.indexOf('.', i + 1)) {
245
++sum;
246
}
247
248
return sum;
249
}
250
251
}
252
253