Skip to content

Commit 90352cd

Browse files
author
duke
committed
Automatic merge of jdk:master into master
2 parents 361d538 + 2926435 commit 90352cd

File tree

9 files changed

+1043
-20
lines changed

9 files changed

+1043
-20
lines changed

src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -147,7 +147,7 @@ protected void engineInit(int keysize, SecureRandom random) {
147147
throw new InvalidParameterException(MSG);
148148
}
149149

150-
SecretKey engineGenerateKey0(boolean tls12) {
150+
protected SecretKey engineGenerateKey0(boolean tls12) {
151151
if (spec == null) {
152152
throw new IllegalStateException(
153153
"TlsPrfGenerator must be initialized");
@@ -163,7 +163,7 @@ SecretKey engineGenerateKey0(boolean tls12) {
163163
spec.getPRFBlockSize()) :
164164
doTLS10PRF(secret, labelBytes, spec.getSeed(), n));
165165
try {
166-
return new SecretKeySpec(prfBytes, "TlsPrf");
166+
return new SecretKeySpec(prfBytes, spec.getKeyAlg());
167167
} finally {
168168
Arrays.fill(prfBytes, (byte)0);
169169
}

src/java.base/share/classes/javax/net/ssl/ExtendedSSLSession.java

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
2626
package javax.net.ssl;
2727

2828
import java.util.List;
29+
import javax.crypto.SecretKey;
2930

3031
/**
3132
* Extends the {@code SSLSession} interface to support additional
@@ -163,4 +164,113 @@ public List<SNIServerName> getRequestedServerNames() {
163164
public List<byte[]> getStatusResponses() {
164165
throw new UnsupportedOperationException();
165166
}
167+
168+
/**
169+
* Generates Exported Keying Material (EKM) calculated according to the
170+
* algorithms defined in RFCs 5705/8446.
171+
* <P>
172+
* RFC 5705 (for (D)TLSv1.2 and earlier) calculates different EKM
173+
* values depending on whether {@code context} is null or non-null/empty.
174+
* RFC 8446 (TLSv1.3) treats a null context as non-null/empty.
175+
* <P>
176+
* {@code label} will be converted to bytes using
177+
* the {@link java.nio.charset.StandardCharsets#UTF_8}
178+
* character encoding.
179+
*
180+
* @spec https://www.rfc-editor.org/info/rfc5705
181+
* RFC 5705: Keying Material Exporters for Transport Layer
182+
* Security (TLS)
183+
* @spec https://www.rfc-editor.org/info/rfc8446
184+
* RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3
185+
*
186+
* @implSpec The default implementation throws
187+
* {@code UnsupportedOperationException}.
188+
*
189+
* @param keyAlg the algorithm of the resultant {@code SecretKey} object.
190+
* See the SecretKey Algorithms section in the
191+
* <a href="{@docRoot}/../specs/security/standard-names.html#secretkey-algorithms">
192+
* Java Security Standard Algorithm Names Specification</a>
193+
* for information about standard secret key algorithm
194+
* names.
195+
* @param label the label bytes used in the EKM calculation.
196+
* {@code label} will be converted to a {@code byte[]}
197+
* before the operation begins.
198+
* @param context the context bytes used in the EKM calculation, or null
199+
* @param length the number of bytes of EKM material needed
200+
*
201+
* @throws SSLKeyException if the key cannot be generated
202+
* @throws IllegalArgumentException if {@code keyAlg} is empty,
203+
* {@code length} is non-positive, or if the {@code label} or
204+
* {@code context} length can not be accommodated
205+
* @throws NullPointerException if {@code keyAlg} or {@code label} is null
206+
* @throws IllegalStateException if this session does not have the
207+
* necessary key generation material (for example, a session
208+
* under construction during handshaking)
209+
* @throws UnsupportedOperationException if the underlying provider
210+
* does not implement the operation
211+
*
212+
* @return a {@code SecretKey} that contains {@code length} bytes of the
213+
* EKM material
214+
*
215+
* @since 25
216+
*/
217+
public SecretKey exportKeyingMaterialKey(String keyAlg,
218+
String label, byte[] context, int length) throws SSLKeyException {
219+
throw new UnsupportedOperationException(
220+
"Underlying provider does not implement the method");
221+
}
222+
223+
/**
224+
* Generates Exported Keying Material (EKM) calculated according to the
225+
* algorithms defined in RFCs 5705/8446.
226+
* <P>
227+
* RFC 5705 (for (D)TLSv1.2 and earlier) calculates different EKM
228+
* values depending on whether {@code context} is null or non-null/empty.
229+
* RFC 8446 (TLSv1.3) treats a null context as non-null/empty.
230+
* <P>
231+
* {@code label} will be converted to bytes using
232+
* the {@link java.nio.charset.StandardCharsets#UTF_8}
233+
* character encoding.
234+
* <P>
235+
* Depending on the chosen underlying key derivation mechanism, the
236+
* raw bytes might not be extractable/exportable. In such cases, the
237+
* {@link #exportKeyingMaterialKey(String, String, byte[], int)} method
238+
* should be used instead to access the generated key material.
239+
*
240+
* @spec https://www.rfc-editor.org/info/rfc5705
241+
* RFC 5705: Keying Material Exporters for Transport Layer
242+
* Security (TLS)
243+
* @spec https://www.rfc-editor.org/info/rfc8446
244+
* RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3
245+
*
246+
* @implSpec The default implementation throws
247+
* {@code UnsupportedOperationException}.
248+
*
249+
* @param label the label bytes used in the EKM calculation.
250+
* {@code label} will be converted to a {@code byte[]}
251+
* before the operation begins.
252+
* @param context the context bytes used in the EKM calculation, or null
253+
* @param length the number of bytes of EKM material needed
254+
*
255+
* @throws SSLKeyException if the key cannot be generated
256+
* @throws IllegalArgumentException if {@code length} is non-positive,
257+
* or if the {@code label} or {@code context} length can
258+
* not be accommodated
259+
* @throws NullPointerException if {@code label} is null
260+
* @throws IllegalStateException if this session does not have the
261+
* necessary key generation material (for example, a session
262+
* under construction during handshaking)
263+
* @throws UnsupportedOperationException if the underlying provider
264+
* does not implement the operation, or if the derived
265+
* keying material is not extractable
266+
*
267+
* @return a byte array of size {@code length} that contains the EKM
268+
* material
269+
* @since 25
270+
*/
271+
public byte[] exportKeyingMaterialData(
272+
String label, byte[] context, int length) throws SSLKeyException {
273+
throw new UnsupportedOperationException(
274+
"Underlying provider does not implement the method");
275+
}
166276
}

src/java.base/share/classes/sun/security/internal/spec/TlsPrfParameterSpec.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,7 @@
4545
public class TlsPrfParameterSpec implements AlgorithmParameterSpec {
4646

4747
private final SecretKey secret;
48+
private final String keyAlg;
4849
private final String label;
4950
private final byte[] seed;
5051
private final int outputLength;
@@ -72,13 +73,45 @@ public class TlsPrfParameterSpec implements AlgorithmParameterSpec {
7273
public TlsPrfParameterSpec(SecretKey secret, String label,
7374
byte[] seed, int outputLength,
7475
String prfHashAlg, int prfHashLength, int prfBlockSize) {
75-
if ((label == null) || (seed == null)) {
76-
throw new NullPointerException("label and seed must not be null");
76+
this(secret, "TlsPrf", label, seed, outputLength, prfHashAlg,
77+
prfHashLength, prfBlockSize);
78+
}
79+
80+
/**
81+
* Constructs a new TlsPrfParameterSpec.
82+
*
83+
* @param secret the secret to use in the calculation (or null)
84+
* @param keyAlg the algorithm name for the generated {@code SecretKey}
85+
* @param label the label to use in the calculation
86+
* @param seed the random seed to use in the calculation
87+
* @param outputLength the length in bytes of the output key to be produced
88+
* @param prfHashAlg the name of the TLS PRF hash algorithm to use.
89+
* Used only for TLS 1.2+. TLS1.1 and earlier use a fixed PRF.
90+
* @param prfHashLength the output length of the TLS PRF hash algorithm.
91+
* Used only for TLS 1.2+.
92+
* @param prfBlockSize the input block size of the TLS PRF hash algorithm.
93+
* Used only for TLS 1.2+.
94+
*
95+
* @throws NullPointerException if keyAlg, label or seed is null
96+
* @throws IllegalArgumentException if outputLength is negative or
97+
* keyAlg is empty
98+
*/
99+
public TlsPrfParameterSpec(SecretKey secret, String keyAlg,
100+
String label, byte[] seed, int outputLength,
101+
String prfHashAlg, int prfHashLength, int prfBlockSize) {
102+
103+
if ((keyAlg == null) || (label == null) || (seed == null)) {
104+
throw new NullPointerException(
105+
"keyAlg, label or seed must not be null");
106+
}
107+
if (keyAlg.isEmpty()) {
108+
throw new IllegalArgumentException("keyAlg can not be empty");
77109
}
78110
if (outputLength <= 0) {
79111
throw new IllegalArgumentException("outputLength must be positive");
80112
}
81113
this.secret = secret;
114+
this.keyAlg = keyAlg;
82115
this.label = label;
83116
this.seed = seed.clone();
84117
this.outputLength = outputLength;
@@ -87,6 +120,15 @@ public TlsPrfParameterSpec(SecretKey secret, String label,
87120
this.prfBlockSize = prfBlockSize;
88121
}
89122

123+
/**
124+
* Returns the key algorithm name to use when generating the SecretKey.
125+
*
126+
* @return the key algorithm name
127+
*/
128+
public String getKeyAlg() {
129+
return keyAlg;
130+
}
131+
90132
/**
91133
* Returns the secret to use in the PRF calculation, or null if there is no
92134
* secret.

src/java.base/share/classes/sun/security/ssl/Finished.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,12 @@ private byte[] onProduceFinished(ClientHandshakeContext chc,
745745
"Failure to derive application secrets", gse);
746746
}
747747

748+
// Calculate/save the exporter_master_secret. It uses
749+
// the same handshakeHash as the client/server app traffic.
750+
SecretKey exporterSecret = kd.deriveKey(
751+
"TlsExporterMasterSecret");
752+
chc.handshakeSession.setExporterMasterSecret(exporterSecret);
753+
748754
// The resumption master secret is stored in the session so
749755
// it can be used after the handshake is completed.
750756
SSLSecretDerivation sd = ((SSLSecretDerivation) kd).forContext(chc);
@@ -1099,6 +1105,12 @@ private void onConsumeFinished(ServerHandshakeContext shc,
10991105
shc.baseReadSecret = readSecret;
11001106
shc.conContext.inputRecord.changeReadCiphers(readCipher);
11011107

1108+
// Calculate/save the exporter_master_secret. It uses
1109+
// the same handshakeHash as the client/server app traffic.
1110+
SecretKey exporterSecret = kd.deriveKey(
1111+
"TlsExporterMasterSecret");
1112+
shc.handshakeSession.setExporterMasterSecret(exporterSecret);
1113+
11021114
// The resumption master secret is stored in the session so
11031115
// it can be used after the handshake is completed.
11041116
shc.handshakeHash.update();

0 commit comments

Comments
 (0)