Line 0
Link Here
|
|
|
1 |
/** |
2 |
* @author Michael Furman |
3 |
*/ |
4 |
package org.apache.catalina.realm; |
5 |
|
6 |
import java.io.ByteArrayInputStream; |
7 |
import java.security.cert.CertificateParsingException; |
8 |
import java.security.cert.X509Certificate; |
9 |
import java.util.Collection; |
10 |
import java.util.Iterator; |
11 |
import java.util.List; |
12 |
|
13 |
import org.apache.juli.logging.Log; |
14 |
import org.apache.juli.logging.LogFactory; |
15 |
|
16 |
import org.bouncycastle.asn1.ASN1InputStream; |
17 |
import org.bouncycastle.asn1.ASN1Sequence; |
18 |
import org.bouncycastle.asn1.ASN1TaggedObject; |
19 |
import org.bouncycastle.asn1.DERObject; |
20 |
import org.bouncycastle.asn1.DERUTF8String; |
21 |
|
22 |
|
23 |
public class SubjectAlternativeNameRetriever extends SubjectDnRetriever { |
24 |
private static final int NOT_EXISTING_TYPE = -1; |
25 |
|
26 |
|
27 |
/** |
28 |
* Logger for this class |
29 |
*/ |
30 |
protected final Log logger = LogFactory.getLog(getClass()); |
31 |
|
32 |
|
33 |
private String alternativeIdentifierConfiguration = null; |
34 |
|
35 |
private int alternativeIdentifierTypeValue = NOT_EXISTING_TYPE; |
36 |
|
37 |
protected SubjectAlternativeNameRetriever(String alternativeIdentifierConfiguration) { |
38 |
setSubjectAlternativeNameGeneralName(alternativeIdentifierConfiguration); |
39 |
} |
40 |
|
41 |
|
42 |
|
43 |
@SuppressWarnings("unchecked") |
44 |
public String getUserIdentifier(X509Certificate clientCert) { |
45 |
if (logger.isDebugEnabled()) { |
46 |
logger.debug("getUserIdentifier(X509Certificate) - start"); |
47 |
} |
48 |
|
49 |
String userIdentifier = null; |
50 |
if (clientCert != null) { |
51 |
if (alternativeIdentifierTypeValue != NOT_EXISTING_TYPE) { |
52 |
boolean foundUserIdentifier = false; |
53 |
try { |
54 |
if (clientCert.getSubjectAlternativeNames() != null) { |
55 |
Collection subjectAlternativeNames = clientCert.getSubjectAlternativeNames(); |
56 |
Iterator iter = subjectAlternativeNames.iterator(); |
57 |
while (iter.hasNext()) { |
58 |
List subjectAlternativeName = (List) iter.next(); |
59 |
Integer type = (Integer) subjectAlternativeName.get(0); |
60 |
if (type.intValue() == alternativeIdentifierTypeValue) { |
61 |
Object subjectAlternativeNameValue = subjectAlternativeName.get(1); |
62 |
if (subjectAlternativeNameValue instanceof String) { |
63 |
userIdentifier = (String) subjectAlternativeNameValue; |
64 |
foundUserIdentifier = true; |
65 |
break; |
66 |
} else if (subjectAlternativeNameValue instanceof byte[]) { |
67 |
byte[] subjectAlternativeNameValueBytes = (byte[]) subjectAlternativeNameValue; |
68 |
userIdentifier = getStringFromASNDerEncodedByteArray(subjectAlternativeNameValueBytes); |
69 |
if (userIdentifier != null) { |
70 |
foundUserIdentifier = true; |
71 |
break; |
72 |
} |
73 |
} else { |
74 |
if (logger.isInfoEnabled()) { |
75 |
logger.info("Can not get UserIdentifier, the subjectAlternativeName not supported [" + subjectAlternativeNameValue + "]."); |
76 |
} |
77 |
} |
78 |
} |
79 |
} |
80 |
} |
81 |
} catch (CertificateParsingException e) { |
82 |
logger.info("Can not get UserIdentifier, can not get subjectAlternativeNames from certificate [" + e.getMessage() + "]."); |
83 |
} |
84 |
if (foundUserIdentifier) { |
85 |
if (logger.isDebugEnabled()) { |
86 |
logger.debug("Found userIdentifier [" + userIdentifier + "] from part of subjectAlternativeName [" + alternativeIdentifierConfiguration + "]."); |
87 |
} |
88 |
} else { |
89 |
if (logger.isDebugEnabled()) { |
90 |
logger.debug("Can not found userIdentifier as part of subjectAlternativeName [" + alternativeIdentifierConfiguration + "]."); |
91 |
} |
92 |
} |
93 |
|
94 |
} else { |
95 |
if (logger.isDebugEnabled()) { |
96 |
logger.debug("Can not get UserIdentifier, generalName is null"); |
97 |
} |
98 |
} |
99 |
} else { |
100 |
if (logger.isDebugEnabled()) { |
101 |
logger.debug("Can not get UserIdentifier, clientCert is null"); |
102 |
} |
103 |
} |
104 |
if (logger.isDebugEnabled()) { |
105 |
logger.debug("getUserIdentifier(X509Certificate) - end; Ret is [" + userIdentifier + "]."); |
106 |
} |
107 |
|
108 |
return userIdentifier; |
109 |
} |
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
private void setSubjectAlternativeNameGeneralName(String alternativeIdentifierConfiguration) { |
116 |
if (logger.isDebugEnabled()) { |
117 |
logger.debug("setSubjectAlternativeNameGeneralName(String) - start; alternativeIdentifier [" + alternativeIdentifierConfiguration + "]."); |
118 |
} |
119 |
this.alternativeIdentifierConfiguration = null; |
120 |
alternativeIdentifierTypeValue = NOT_EXISTING_TYPE; |
121 |
|
122 |
if (alternativeIdentifierConfiguration != null) { |
123 |
this.alternativeIdentifierConfiguration = alternativeIdentifierConfiguration; |
124 |
String alternativeIdentifierConfigurationLowerCase = alternativeIdentifierConfiguration.toLowerCase(); |
125 |
if ((ClientCertificateConstants.SubjectAlternativeNameGeneralNames.otherName.equalsIgnoreCase (alternativeIdentifierConfiguration)) |
126 |
|| (ClientCertificateConstants.OtherNameOptions.contains(alternativeIdentifierConfigurationLowerCase))) { |
127 |
alternativeIdentifierTypeValue = ClientCertificateConstants.SubjectAlternativeNameGeneralNames.otherName.ordinal(); |
128 |
} else if ((ClientCertificateConstants.SubjectAlternativeNameGeneralNames.rfc822Name.equalsIgnoreCase (alternativeIdentifierConfiguration)) |
129 |
|| (ClientCertificateConstants.RFC822NameOptions.contains(alternativeIdentifierConfigurationLowerCase))) { |
130 |
alternativeIdentifierTypeValue = ClientCertificateConstants.SubjectAlternativeNameGeneralNames.rfc822Name.ordinal(); |
131 |
} else if ((ClientCertificateConstants.SubjectAlternativeNameGeneralNames.dNSName.equalsIgnoreCase (alternativeIdentifierConfiguration)) |
132 |
|| (ClientCertificateConstants.DNSNameOptions.contains(alternativeIdentifierConfigurationLowerCase))) { |
133 |
alternativeIdentifierTypeValue = ClientCertificateConstants.SubjectAlternativeNameGeneralNames.dNSName.ordinal(); |
134 |
} else if (ClientCertificateConstants.SubjectAlternativeNameGeneralNames.x400Address.equalsIgnoreCase (alternativeIdentifierConfiguration)) { |
135 |
alternativeIdentifierTypeValue = ClientCertificateConstants.SubjectAlternativeNameGeneralNames.x400Address.ordinal(); |
136 |
} else if ((ClientCertificateConstants.SubjectAlternativeNameGeneralNames.directoryName.equalsIgnoreCase (alternativeIdentifierConfiguration)) |
137 |
|| (ClientCertificateConstants.DirectoryNameOptions.contains(alternativeIdentifierConfigurationLowerCase))) { |
138 |
alternativeIdentifierTypeValue = ClientCertificateConstants.SubjectAlternativeNameGeneralNames.directoryName.ordinal(); |
139 |
} else if (ClientCertificateConstants.SubjectAlternativeNameGeneralNames.ediPartyName.equalsIgnoreCase (alternativeIdentifierConfiguration)) { |
140 |
alternativeIdentifierTypeValue = ClientCertificateConstants.SubjectAlternativeNameGeneralNames.ediPartyName.ordinal(); |
141 |
} else if ((ClientCertificateConstants.SubjectAlternativeNameGeneralNames.uniformResourceIdentifier.equalsIgnoreCase (alternativeIdentifierConfiguration)) |
142 |
|| (ClientCertificateConstants.UriOptions.contains(alternativeIdentifierConfigurationLowerCase))) { |
143 |
alternativeIdentifierTypeValue = ClientCertificateConstants.SubjectAlternativeNameGeneralNames.uniformResourceIdentifier.ordinal(); |
144 |
} else if ((ClientCertificateConstants.SubjectAlternativeNameGeneralNames.iPAddress.equalsIgnoreCase (alternativeIdentifierConfiguration)) |
145 |
|| (ClientCertificateConstants.IPAddressOptions.contains(alternativeIdentifierConfigurationLowerCase))) { |
146 |
alternativeIdentifierTypeValue = ClientCertificateConstants.SubjectAlternativeNameGeneralNames.iPAddress.ordinal(); |
147 |
} else if ((ClientCertificateConstants.SubjectAlternativeNameGeneralNames.registeredID.equalsIgnoreCase (alternativeIdentifierConfiguration)) |
148 |
|| (ClientCertificateConstants.RegisteredIDOptions.contains(alternativeIdentifierConfigurationLowerCase))) { |
149 |
alternativeIdentifierTypeValue = ClientCertificateConstants.SubjectAlternativeNameGeneralNames.registeredID.ordinal(); |
150 |
} else { |
151 |
try { |
152 |
alternativeIdentifierTypeValue = (new Integer(alternativeIdentifierConfiguration)).intValue(); |
153 |
}catch (NumberFormatException e) { |
154 |
alternativeIdentifierTypeValue = NOT_EXISTING_TYPE; |
155 |
} |
156 |
} |
157 |
|
158 |
} |
159 |
if (logger.isDebugEnabled()) { |
160 |
logger.debug("setSubjectAlternativeNameGeneralName(String) - end; alternativeIdentifier [" + alternativeIdentifierConfiguration + "], alternativeIdentifierType [" + alternativeIdentifierTypeValue + "]."); |
161 |
} |
162 |
} |
163 |
|
164 |
|
165 |
private String getStringFromASNDerEncodedByteArray(byte[] byteArray) { |
166 |
if (logger.isDebugEnabled()) { |
167 |
logger.debug("getStringFromASNDerEncodedByteArray(byte[]) - start"); |
168 |
} |
169 |
|
170 |
String ret = null; |
171 |
try { |
172 |
ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(byteArray)); |
173 |
DERObject derObject = asn1InputStream.readObject(); |
174 |
ASN1Sequence asn1Sequence = ASN1Sequence.getInstance(derObject); |
175 |
Object objectValue = asn1Sequence.getObjectAt(1); |
176 |
if (objectValue instanceof ASN1TaggedObject) { |
177 |
ASN1TaggedObject asn1TaggedObject = (ASN1TaggedObject) objectValue; |
178 |
try { |
179 |
if (logger.isDebugEnabled()) { |
180 |
logger.debug("Try to get string from DERUTF8String."); |
181 |
} |
182 |
DERObject derTaggedObject = asn1TaggedObject.getObject(); |
183 |
DERUTF8String derUtf8String = DERUTF8String.getInstance(derTaggedObject); |
184 |
ret = derUtf8String.getString(); |
185 |
} catch (IllegalArgumentException e) { |
186 |
if (logger.isDebugEnabled()) { |
187 |
logger.debug("Can not get String From DERUTF8String, [" + e.getMessage() + "]."); |
188 |
} |
189 |
} |
190 |
} |
191 |
} catch (Exception e) { |
192 |
if (logger.isInfoEnabled()) { |
193 |
logger.info("Can not get String From ASNDerEncoded ByteArray, [" + e.getMessage() + "]."); |
194 |
} |
195 |
} |
196 |
|
197 |
if (logger.isDebugEnabled()) { |
198 |
logger.debug("getStringFromASNDerEncodedByteArray(byte[]) - end. Ret is [" + ret + "]."); |
199 |
} |
200 |
return ret; |
201 |
|
202 |
} |
203 |
|
204 |
|
205 |
} |