/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* KeyGenerator implementation for the TLS PRF function.
* <p>
* This class duplicates the HMAC functionality (RFC 2104) with
* performance optimizations (e.g. XOR'ing keys with padding doesn't
* need to be redone for each HMAC operation).
*
* @author Andreas Sterbenz
* @since 1.6
*/
// magic constants and utility functions, also used by other files
// in this package
{ 109, 97, 115, 116, 101, 114, 32, 115, 101, 99, 114, 101, 116 };
{ 107, 101, 121, 32, 101, 120, 112, 97, 110, 115, 105, 111, 110 };
{ 99, 108, 105, 101, 110, 116, 32, 119, 114, 105, 116, 101, 32,
107, 101, 121 };
{ 115, 101, 114, 118, 101, 114, 32, 119, 114, 105, 116, 101, 32,
107, 101, 121 };
{ 73, 86, 32, 98, 108, 111, 99, 107 };
/*
* TLS HMAC "inner" and "outer" padding. This isn't a function
* of the digest algorithm.
*/
// SSL3 magic mix constants ("A", "BB", "CCC", ...)
return padding;
}
return b;
}
private static byte[][] genConst() {
int n = 10;
byte[][] arr = new byte[n][];
for (int i = 0; i < n; i++) {
byte[] b = new byte[i + 1];
arr[i] = b;
}
return arr;
}
// PRF implementation
+ "initialized using a TlsPrfParameterSpec";
public TlsPrfGenerator() {
}
throw new InvalidParameterException(MSG);
}
if (params instanceof TlsPrfParameterSpec == false) {
throw new InvalidAlgorithmParameterException(MSG);
}
throw new InvalidAlgorithmParameterException(
"Key encoding format must be RAW");
}
}
throw new InvalidParameterException(MSG);
}
throw new IllegalStateException(
"TlsPrfGenerator must be initialized");
}
try {
int n = spec.getOutputLength();
spec.getPRFBlockSize()) :
} catch (GeneralSecurityException e) {
throw new ProviderException("Could not generate PRF", e);
throw new ProviderException("Could not generate PRF", e);
}
}
byte[] seed, int outputLength,
throws NoSuchAlgorithmException, DigestException {
throw new NoSuchAlgorithmException("Unspecified PRF algorithm");
}
}
byte[] seed, int outputLength,
throws DigestException {
}
// If we have a long secret, digest it first.
}
byte[] output = new byte[outputLength];
byte [] ipad;
byte [] opad;
switch (mdPRFBlockSize) {
case 64:
break;
case 128:
break;
default:
throw new DigestException("Unexpected block size.");
}
// P_HASH(Secret, label + seed)
return output;
}
}
/*
* Split the secret into two halves S1 and S2 of same length.
* S1 is taken from the first half of the secret, S2 from the
* second half.
* Their length is created by rounding up the length of the
* overall secret divided by two; thus, if the original secret
* is an odd number of bytes long, the last byte of S1 will be
* the same as the first byte of S2.
*
* Note: Instead of creating S1 and S2, we determine the offset into
* the overall secret where S2 starts.
*/
}
byte[] output = new byte[outputLength];
// P_MD5(S1, label + seed)
// P_SHA-1(S2, label + seed)
return output;
}
/*
* @param digest the MessageDigest to produce the HMAC
* @param hmacSize the HMAC size
* @param secret the secret
* @param secOff the offset into the secret
* @param secLen the secret length
* @param label the label
* @param seed the seed
* @param output the output array
*/
/*
* modify the padding used, by XORing the key into our copy of that
* padding. That's to avoid doing that for each HMAC computation.
*/
for (int i = 0; i < secLen; i++) {
}
/*
* compute:
*
* P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
* HMAC_hash(secret, A(2) + seed) +
* HMAC_hash(secret, A(3) + seed) + ...
* A() is defined as:
*
* A(0) = seed
* A(i) = HMAC_hash(secret, A(i-1))
*/
int ofs = 0;
while (remaining > 0) {
/*
* compute A() ...
*/
// inner digest
} else {
}
// outer digest
}
/*
* compute HMAC_hash() ...
*/
// inner digest
// outer digest
for (int i = 0; i < k; i++) {
}
remaining -= k;
}
}
/**
* A KeyGenerator implementation that supports TLS 1.2.
* <p>
* TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the PRF
* calculations. As of 2010, there is no PKCS11-level support for TLS
* 1.2 PRF calculations, and no known OS's have an internal variant
* we could use. Therefore for TLS 1.2, we are updating JSSE to request
* a different provider algorithm: "SunTls12Prf". If we reused the
* name "SunTlsPrf", the PKCS11 provider would need be updated to
* fail correctly when presented with the wrong version number
* (via Provider.Service.supportsParameters()), and add the
* appropriate supportsParamters() checks into KeyGenerators (not
* currently there).
*/
return engineGenerateKey0(true);
}
}
/**
* A KeyGenerator implementation that supports TLS 1.0/1.1.
*/
return engineGenerateKey0(false);
}
}
}