Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.security.sasl/share/classes/com/sun/security/sasl/CramMD5Base.java
41161 views
1
/*
2
* Copyright (c) 2003, 2020, 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 com.sun.security.sasl;
27
28
import javax.security.sasl.SaslException;
29
import javax.security.sasl.Sasl;
30
31
// For HMAC_MD5
32
import java.security.NoSuchAlgorithmException;
33
import java.security.MessageDigest;
34
35
import java.util.Arrays;
36
import java.util.logging.Logger;
37
38
/**
39
* Base class for implementing CRAM-MD5 client and server mechanisms.
40
*
41
* @author Vincent Ryan
42
* @author Rosanna Lee
43
*/
44
abstract class CramMD5Base {
45
protected boolean completed = false;
46
protected boolean aborted = false;
47
protected byte[] pw;
48
49
protected CramMD5Base() {
50
initLogger();
51
}
52
53
/**
54
* Retrieves this mechanism's name.
55
*
56
* @return The string "CRAM-MD5".
57
*/
58
public String getMechanismName() {
59
return "CRAM-MD5";
60
}
61
62
/**
63
* Determines whether this mechanism has completed.
64
* CRAM-MD5 completes after processing one challenge from the server.
65
*
66
* @return true if has completed; false otherwise;
67
*/
68
public boolean isComplete() {
69
return completed;
70
}
71
72
/**
73
* Unwraps the incoming buffer. CRAM-MD5 supports no security layer.
74
*
75
* @throws SaslException If attempt to use this method.
76
*/
77
public byte[] unwrap(byte[] incoming, int offset, int len)
78
throws SaslException {
79
if (completed) {
80
throw new IllegalStateException(
81
"CRAM-MD5 supports neither integrity nor privacy");
82
} else {
83
throw new IllegalStateException(
84
"CRAM-MD5 authentication not completed");
85
}
86
}
87
88
/**
89
* Wraps the outgoing buffer. CRAM-MD5 supports no security layer.
90
*
91
* @throws SaslException If attempt to use this method.
92
*/
93
public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException {
94
if (completed) {
95
throw new IllegalStateException(
96
"CRAM-MD5 supports neither integrity nor privacy");
97
} else {
98
throw new IllegalStateException(
99
"CRAM-MD5 authentication not completed");
100
}
101
}
102
103
/**
104
* Retrieves the negotiated property.
105
* This method can be called only after the authentication exchange has
106
* completed (i.e., when {@code isComplete()} returns true); otherwise, a
107
* {@code SaslException} is thrown.
108
*
109
* @return value of property; only QOP is applicable to CRAM-MD5.
110
* @exception IllegalStateException if this authentication exchange has not completed
111
*/
112
public Object getNegotiatedProperty(String propName) {
113
if (completed) {
114
if (propName.equals(Sasl.QOP)) {
115
return "auth";
116
} else {
117
return null;
118
}
119
} else {
120
throw new IllegalStateException(
121
"CRAM-MD5 authentication not completed");
122
}
123
}
124
125
public void dispose() throws SaslException {
126
clearPassword();
127
}
128
129
protected void clearPassword() {
130
if (pw != null) {
131
// zero out password
132
for (int i = 0; i < pw.length; i++) {
133
pw[i] = (byte)0;
134
}
135
pw = null;
136
}
137
}
138
139
@SuppressWarnings("deprecation")
140
protected void finalize() {
141
clearPassword();
142
}
143
144
private static final int MD5_BLOCKSIZE = 64;
145
/**
146
* Hashes its input arguments according to HMAC-MD5 (RFC 2104)
147
* and returns the resulting digest in its ASCII representation.
148
*
149
* HMAC-MD5 function is described as follows:
150
*
151
* MD5(key XOR opad, MD5(key XOR ipad, text))
152
*
153
* where key is an n byte key
154
* ipad is the byte 0x36 repeated 64 times
155
* opad is the byte 0x5c repeated 64 times
156
* text is the data to be protected
157
*/
158
static final String HMAC_MD5(byte[] key, byte[] text)
159
throws NoSuchAlgorithmException {
160
161
MessageDigest md5 = MessageDigest.getInstance("MD5");
162
163
/* digest the key if longer than 64 bytes */
164
if (key.length > MD5_BLOCKSIZE) {
165
key = md5.digest(key);
166
}
167
168
byte[] ipad = new byte[MD5_BLOCKSIZE]; /* inner padding */
169
byte[] opad = new byte[MD5_BLOCKSIZE]; /* outer padding */
170
byte[] digest;
171
int i;
172
173
/* store key in pads */
174
for (i = 0; i < key.length; i++) {
175
ipad[i] = key[i];
176
opad[i] = key[i];
177
}
178
179
/* XOR key with pads */
180
for (i = 0; i < MD5_BLOCKSIZE; i++) {
181
ipad[i] ^= 0x36;
182
opad[i] ^= 0x5c;
183
}
184
185
/* inner MD5 */
186
md5.update(ipad);
187
md5.update(text);
188
digest = md5.digest();
189
190
/* outer MD5 */
191
md5.update(opad);
192
md5.update(digest);
193
digest = md5.digest();
194
195
// Get character representation of digest
196
StringBuilder digestString = new StringBuilder();
197
198
for (i = 0; i < digest.length; i++) {
199
if ((digest[i] & 0x000000ff) < 0x10) {
200
digestString.append('0').append(Integer.toHexString(digest[i] & 0x000000ff));
201
} else {
202
digestString.append(
203
Integer.toHexString(digest[i] & 0x000000ff));
204
}
205
}
206
207
Arrays.fill(ipad, (byte)0);
208
Arrays.fill(opad, (byte)0);
209
ipad = null;
210
opad = null;
211
212
return (digestString.toString());
213
}
214
215
/**
216
* Sets logger field.
217
*/
218
private static synchronized void initLogger() {
219
if (logger == null) {
220
logger = Logger.getLogger(SASL_LOGGER_NAME);
221
}
222
}
223
/**
224
* Logger for debug messages
225
*/
226
private static final String SASL_LOGGER_NAME = "javax.security.sasl";
227
protected static Logger logger; // set in initLogger(); lazily loads logger
228
}
229
230