PseudoRandomFunction { public static byte[] compute(PRFAlgorithm prfAlgorithm, byte[] secret, String label, byte[] seed, int size) throws CryptoException { if (prfAlgorithm == null) { LOGGER.warn("Trying to compute PRF without specified PRF algorithm. Using TLS 1.0/TLS 1.1 as default."); prfAlgorithm = PRFAlgorithm.TLS_PRF_LEGACY; } switch (prfAlgorithm) { case TLS_PRF_SHA256: case TLS_PRF_SHA384: case TLS_PRF_GOSTR3411: case TLS_PRF_GOSTR3411_2012_256: return computeTls12(secret, label, seed, size, prfAlgorithm.getMacAlgorithm().getJavaName()); case TLS_PRF_LEGACY: return TlsUtils.PRF_legacy(secret, label, seed, size); default: throw new UnsupportedOperationException("PRF computation for different" + " protocol versions is not supported yet"); } } private  PseudoRandomFunction(); static byte[] compute(PRFAlgorithm prfAlgorithm, byte[] secret, String label, byte[] seed, int size); static final String MASTER_SECRET_LABEL; static final String CLIENT_FINISHED_LABEL; static final String SERVER_FINISHED_LABEL; static final String KEY_EXPANSION_LABEL; static final String EXTENDED_MASTER_SECRET_LABEL; static final String CLIENT_WRITE_KEY_LABEL; static final String SERVER_WRITE_KEY_LABEL; static final String IV_BLOCK_LABEL; }
@Test public void testComputeForTls12(@Mocked final TlsContext mockedTlsContext, @Mocked final SecurityParameters mockedParameters) throws CryptoException { new Expectations() { { mockedTlsContext.getServerVersion(); result = ProtocolVersion.TLSv12; } { mockedTlsContext.getSecurityParameters(); result = mockedParameters; } { mockedParameters.getPrfAlgorithm(); result = 1; } }; byte[] secret = new byte[48]; String label = "master secret"; byte[] seed = new byte[60]; Random r = new Random(); r.nextBytes(seed); int size = 48; byte[] result1 = TlsUtils.PRF(mockedTlsContext, secret, label, seed, size); byte[] result2 = PseudoRandomFunction.compute(PRFAlgorithm.TLS_PRF_SHA256, secret, label, seed, size); assertArrayEquals(result1, result2); new Expectations() { { mockedParameters.getPrfAlgorithm(); result = 2; } }; result1 = TlsUtils.PRF(mockedTlsContext, secret, label, seed, size); result2 = PseudoRandomFunction.compute(PRFAlgorithm.TLS_PRF_SHA384, secret, label, seed, size); assertArrayEquals(result1, result2); Security.addProvider(new BouncyCastleProvider()); seed = ArrayConverter .hexStringToByteArray("DD65AFF37A86CD3BECFAF84BE5C85787009FCE23DED71B513EC6F97BA44CF654C6891E4146BBE9DE33DFE9936917C47ED8810D90DDFA90CBDFFAEAD7"); result1 = ArrayConverter .hexStringToByteArray("49BC96FF7CB5A404DFBE1F06CFE49A01D728BDBCDA0FDD87F9B349FF9E2537959F2D0DB3C4480E2C1916D19C2FF5623D"); result2 = PseudoRandomFunction.compute(PRFAlgorithm.TLS_PRF_GOSTR3411, secret, label, seed, size); assertArrayEquals(result1, result2); secret = ArrayConverter .hexStringToByteArray("0DA8674196F2496C4EE1E4779DE04990BE3CE4655252F1961E707B61178436131369D11E7DA84C05374535B95550DD0F"); seed = ArrayConverter .hexStringToByteArray("52E78F4F4E131F8CABAFD5D7C9C62A5EDF62CADB4D033131FE9B83DE9D459EFD52E78F4F6AA0FE312217AEF691AD763932945E8CEDD7F96E3C336B0866A66698"); result1 = ArrayConverter .hexStringToByteArray("6622B653451DBB85BA0494959A6255F02100B93FCF09AF94176A3CA6E7FD09DCDA0357FE5AF3110EBC7B2466B66AB37E"); result2 = PseudoRandomFunction.compute(PRFAlgorithm.TLS_PRF_GOSTR3411_2012_256, secret, label, seed, size); assertArrayEquals(result1, result2); }
@Test public void testComputeForTls11() throws CryptoException { byte[] secret = new byte[48]; String label = "master secret"; byte[] seed = new byte[60]; Random r = new Random(); r.nextBytes(seed); int size = 48; byte[] result1 = TlsUtils.PRF_legacy(secret, label, seed, size); byte[] result2 = PseudoRandomFunction.compute(PRFAlgorithm.TLS_PRF_LEGACY, secret, label, seed, size); assertArrayEquals(result1, result2); }