Skip to content

Commit f63c4a8

Browse files
committedOct 4, 2021
8274471: Verification of OCSP Response signed with RSASSA-PSS fails
Reviewed-by: hchao, jnimeh
1 parent f2404d6 commit f63c4a8

File tree

9 files changed

+65
-86
lines changed

9 files changed

+65
-86
lines changed
 

‎src/java.base/share/classes/sun/security/provider/certpath/OCSP.java

+10-8
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import java.security.cert.CertPathValidatorException.BasicReason;
3636
import java.security.cert.CRLReason;
3737
import java.security.cert.Extension;
38-
import java.security.cert.TrustAnchor;
3938
import java.security.cert.X509Certificate;
4039
import java.util.Base64;
4140
import java.util.Date;
@@ -46,7 +45,6 @@
4645
import sun.security.util.Debug;
4746
import sun.security.util.Event;
4847
import sun.security.util.IOUtils;
49-
import sun.security.validator.Validator;
5048
import sun.security.x509.AccessDescription;
5149
import sun.security.x509.AuthorityInfoAccessExtension;
5250
import sun.security.x509.GeneralName;
@@ -166,22 +164,26 @@ public static byte[] getOCSPBytes(List<CertId> certIds, URI responderURI,
166164
List<Extension> extensions) throws IOException {
167165
OCSPRequest request = new OCSPRequest(certIds, extensions);
168166
byte[] bytes = request.encodeBytes();
167+
String responder = responderURI.toString();
169168

170169
if (debug != null) {
171-
debug.println("connecting to OCSP service at: " + responderURI);
170+
debug.println("connecting to OCSP service at: " + responder);
172171
}
173172
Event.report(Event.ReporterCategory.CRLCHECK, "event.ocsp.check",
174-
responderURI.toString());
173+
responder);
175174

176175
URL url;
177176
HttpURLConnection con = null;
178177
try {
179-
String encodedGetReq = responderURI.toString() + "/" +
180-
URLEncoder.encode(Base64.getEncoder().encodeToString(bytes),
181-
UTF_8);
178+
StringBuilder encodedGetReq = new StringBuilder(responder);
179+
if (!responder.endsWith("/")) {
180+
encodedGetReq.append("/");
181+
}
182+
encodedGetReq.append(URLEncoder.encode(
183+
Base64.getEncoder().encodeToString(bytes), UTF_8));
182184

183185
if (encodedGetReq.length() <= 255) {
184-
url = new URL(encodedGetReq);
186+
url = new URL(encodedGetReq.toString());
185187
con = (HttpURLConnection)url.openConnection();
186188
con.setDoOutput(true);
187189
con.setDoInput(true);

‎src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,10 @@ private boolean verifySignature(X509Certificate cert)
638638

639639
try {
640640
Signature respSignature = Signature.getInstance(sigAlgId.getName());
641-
respSignature.initVerify(cert.getPublicKey());
641+
SignatureUtil.initVerifyWithParam(respSignature,
642+
cert.getPublicKey(),
643+
SignatureUtil.getParamSpec(sigAlgId.getName(),
644+
sigAlgId.getEncodedParams()));
642645
respSignature.update(tbsResponseData);
643646

644647
if (respSignature.verify(signature)) {
@@ -654,8 +657,8 @@ private boolean verifySignature(X509Certificate cert)
654657
}
655658
return false;
656659
}
657-
} catch (InvalidKeyException | NoSuchAlgorithmException |
658-
SignatureException e)
660+
} catch (InvalidAlgorithmParameterException | InvalidKeyException
661+
| NoSuchAlgorithmException | SignatureException e)
659662
{
660663
throw new CertPathValidatorException(e);
661664
}

‎src/java.base/share/classes/sun/security/util/SignatureUtil.java

+10-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2021, 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
@@ -170,8 +170,7 @@ public static AlgorithmParameterSpec getParamSpec(String sigName,
170170
// for verification with the specified key and params (may be null)
171171
public static void initVerifyWithParam(Signature s, PublicKey key,
172172
AlgorithmParameterSpec params)
173-
throws ProviderException, InvalidAlgorithmParameterException,
174-
InvalidKeyException {
173+
throws InvalidAlgorithmParameterException, InvalidKeyException {
175174
SharedSecrets.getJavaSecuritySignatureAccess().initVerify(s, key, params);
176175
}
177176

@@ -180,17 +179,15 @@ public static void initVerifyWithParam(Signature s, PublicKey key,
180179
public static void initVerifyWithParam(Signature s,
181180
java.security.cert.Certificate cert,
182181
AlgorithmParameterSpec params)
183-
throws ProviderException, InvalidAlgorithmParameterException,
184-
InvalidKeyException {
182+
throws InvalidAlgorithmParameterException, InvalidKeyException {
185183
SharedSecrets.getJavaSecuritySignatureAccess().initVerify(s, cert, params);
186184
}
187185

188186
// Utility method for initializing the specified Signature object
189187
// for signing with the specified key and params (may be null)
190188
public static void initSignWithParam(Signature s, PrivateKey key,
191189
AlgorithmParameterSpec params, SecureRandom sr)
192-
throws ProviderException, InvalidAlgorithmParameterException,
193-
InvalidKeyException {
190+
throws InvalidAlgorithmParameterException, InvalidKeyException {
194191
SharedSecrets.getJavaSecuritySignatureAccess().initSign(s, key, params, sr);
195192
}
196193

@@ -342,10 +339,10 @@ public static AlgorithmParameterSpec getDefaultParamSpec(
342339
* Create a Signature that has been initialized with proper key and params.
343340
*
344341
* @param sigAlg signature algorithms
345-
* @param key public or private key
342+
* @param key private key
346343
* @param provider (optional) provider
347344
*/
348-
public static Signature fromKey(String sigAlg, Key key, String provider)
345+
public static Signature fromKey(String sigAlg, PrivateKey key, String provider)
349346
throws NoSuchAlgorithmException, NoSuchProviderException,
350347
InvalidKeyException{
351348
Signature sigEngine = (provider == null || provider.isEmpty())
@@ -358,28 +355,23 @@ public static Signature fromKey(String sigAlg, Key key, String provider)
358355
* Create a Signature that has been initialized with proper key and params.
359356
*
360357
* @param sigAlg signature algorithms
361-
* @param key public or private key
358+
* @param key private key
362359
* @param provider (optional) provider
363360
*/
364-
public static Signature fromKey(String sigAlg, Key key, Provider provider)
361+
public static Signature fromKey(String sigAlg, PrivateKey key, Provider provider)
365362
throws NoSuchAlgorithmException, InvalidKeyException{
366363
Signature sigEngine = (provider == null)
367364
? Signature.getInstance(sigAlg)
368365
: Signature.getInstance(sigAlg, provider);
369366
return autoInitInternal(sigAlg, key, sigEngine);
370367
}
371368

372-
private static Signature autoInitInternal(String alg, Key key, Signature s)
369+
private static Signature autoInitInternal(String alg, PrivateKey key, Signature s)
373370
throws InvalidKeyException {
374371
AlgorithmParameterSpec params = SignatureUtil
375372
.getDefaultParamSpec(alg, key);
376373
try {
377-
if (key instanceof PrivateKey) {
378-
SignatureUtil.initSignWithParam(s, (PrivateKey) key, params,
379-
null);
380-
} else {
381-
SignatureUtil.initVerifyWithParam(s, (PublicKey) key, params);
382-
}
374+
SignatureUtil.initSignWithParam(s, key, params, null);
383375
} catch (InvalidAlgorithmParameterException e) {
384376
throw new AssertionError("Should not happen", e);
385377
}

‎src/java.base/share/classes/sun/security/x509/AlgorithmId.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ public AlgorithmParameters getParameters() {
312312
*
313313
* @return DER encoded parameters, or null not present.
314314
*/
315-
public byte[] getEncodedParams() throws IOException {
315+
public byte[] getEncodedParams() {
316316
return (encodedParams == null ||
317317
algid.toString().equals(KnownOIDs.SpecifiedSHA2withECDSA.value()))
318318
? null

‎src/java.base/share/classes/sun/security/x509/X509CRLImpl.java

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2021, 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
@@ -820,13 +820,7 @@ public String getSigAlgOID() {
820820
* null if no parameters are present.
821821
*/
822822
public byte[] getSigAlgParams() {
823-
if (sigAlgId == null)
824-
return null;
825-
try {
826-
return sigAlgId.getEncodedParams();
827-
} catch (IOException e) {
828-
return null;
829-
}
823+
return sigAlgId == null ? null : sigAlgId.getEncodedParams();
830824
}
831825

832826
/**

‎src/java.base/share/classes/sun/security/x509/X509CertImpl.java

+1-7
Original file line numberDiff line numberDiff line change
@@ -1030,13 +1030,7 @@ public String getSigAlgOID() {
10301030
* null if no parameters are present.
10311031
*/
10321032
public byte[] getSigAlgParams() {
1033-
if (algId == null)
1034-
return null;
1035-
try {
1036-
return algId.getEncodedParams();
1037-
} catch (IOException e) {
1038-
return null;
1039-
}
1033+
return algId == null ? null : algId.getEncodedParams();
10401034
}
10411035

10421036
/**

‎test/jdk/java/security/testlibrary/CertificateBuilder.java

+15-27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2021, 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
@@ -38,6 +38,7 @@
3838
import sun.security.util.DerOutputStream;
3939
import sun.security.util.DerValue;
4040
import sun.security.util.ObjectIdentifier;
41+
import sun.security.util.SignatureUtil;
4142
import sun.security.x509.AccessDescription;
4243
import sun.security.x509.AlgorithmId;
4344
import sun.security.x509.AuthorityInfoAccessExtension;
@@ -364,8 +365,7 @@ public X509Certificate build(X509Certificate issuerCert,
364365
throws IOException, CertificateException, NoSuchAlgorithmException {
365366
// TODO: add some basic checks (key usage, basic constraints maybe)
366367

367-
AlgorithmId signAlg = AlgorithmId.get(algName);
368-
byte[] encodedCert = encodeTopLevel(issuerCert, issuerKey, signAlg);
368+
byte[] encodedCert = encodeTopLevel(issuerCert, issuerKey, algName);
369369
ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert);
370370
return (X509Certificate)factory.generateCertificate(bais);
371371
}
@@ -392,18 +392,24 @@ public X509Certificate build(X509Certificate issuerCert,
392392
* @throws IOException if an encoding error occurs.
393393
*/
394394
private byte[] encodeTopLevel(X509Certificate issuerCert,
395-
PrivateKey issuerKey, AlgorithmId signAlg)
396-
throws CertificateException, IOException {
395+
PrivateKey issuerKey, String algName)
396+
throws CertificateException, IOException, NoSuchAlgorithmException {
397+
398+
AlgorithmId signAlg = AlgorithmId.get(algName);
397399
DerOutputStream outerSeq = new DerOutputStream();
398400
DerOutputStream topLevelItems = new DerOutputStream();
399401

400-
tbsCertBytes = encodeTbsCert(issuerCert, signAlg);
401-
topLevelItems.write(tbsCertBytes);
402402
try {
403-
signatureBytes = signCert(issuerKey, signAlg);
403+
Signature sig = SignatureUtil.fromKey(signAlg.getName(), issuerKey, (Provider)null);
404+
// Rewrite signAlg, RSASSA-PSS needs some parameters.
405+
signAlg = SignatureUtil.fromSignature(sig, issuerKey);
406+
tbsCertBytes = encodeTbsCert(issuerCert, signAlg);
407+
sig.update(tbsCertBytes);
408+
signatureBytes = sig.sign();
404409
} catch (GeneralSecurityException ge) {
405410
throw new CertificateException(ge);
406411
}
412+
topLevelItems.write(tbsCertBytes);
407413
signAlg.derEncode(topLevelItems);
408414
topLevelItems.putBitString(signatureBytes);
409415
outerSeq.write(DerValue.tag_Sequence, topLevelItems);
@@ -518,22 +524,4 @@ private void encodeExtensions(DerOutputStream tbsStream)
518524
(byte)3), extSequence);
519525
}
520526

521-
/**
522-
* Digitally sign the X.509 certificate.
523-
*
524-
* @param issuerKey The private key of the issuing authority
525-
* @param signAlg The signature algorithm object
526-
*
527-
* @return The digital signature bytes.
528-
*
529-
* @throws GeneralSecurityException If any errors occur during the
530-
* digital signature process.
531-
*/
532-
private byte[] signCert(PrivateKey issuerKey, AlgorithmId signAlg)
533-
throws GeneralSecurityException {
534-
Signature sig = Signature.getInstance(signAlg.getName());
535-
sig.initSign(issuerKey);
536-
sig.update(tbsCertBytes);
537-
return sig.sign();
538-
}
539-
}
527+
}

‎test/jdk/java/security/testlibrary/SimpleOCSPServer.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2021, 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
@@ -174,8 +174,7 @@ public SimpleOCSPServer(InetAddress addr, int port, KeyStore ks,
174174
issuerAlias + " not found");
175175
}
176176
}
177-
178-
sigAlgId = AlgorithmId.get("Sha256withRSA");
177+
sigAlgId = AlgorithmId.get(SignatureUtil.getDefaultSigAlgForKey(signerKey));
179178
respId = new ResponderId(signerCert.getSubjectX500Principal());
180179
listenAddress = addr;
181180
listenPort = port;
@@ -1348,13 +1347,14 @@ private byte[] encodeBasicOcspResponse() throws IOException {
13481347
basicORItemStream.write(tbsResponseBytes);
13491348

13501349
try {
1351-
sigAlgId.derEncode(basicORItemStream);
1352-
13531350
// Create the signature
1354-
Signature sig = Signature.getInstance(sigAlgId.getName());
1355-
sig.initSign(signerKey);
1351+
Signature sig = SignatureUtil.fromKey(
1352+
sigAlgId.getName(), signerKey, (Provider)null);
13561353
sig.update(tbsResponseBytes);
13571354
signature = sig.sign();
1355+
// Rewrite signAlg, RSASSA-PSS needs some parameters.
1356+
sigAlgId = SignatureUtil.fromSignature(sig, signerKey);
1357+
sigAlgId.derEncode(basicORItemStream);
13581358
basicORItemStream.putBitString(signature);
13591359
} catch (GeneralSecurityException exc) {
13601360
err(exc);

‎test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2021, 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
@@ -30,7 +30,8 @@
3030
* @summary OCSP Stapling for TLS
3131
* @library ../../../../java/security/testlibrary
3232
* @build CertificateBuilder SimpleOCSPServer
33-
* @run main/othervm HttpsUrlConnClient
33+
* @run main/othervm HttpsUrlConnClient RSA SHA256withRSA
34+
* @run main/othervm HttpsUrlConnClient RSASSA-PSS RSASSA-PSS
3435
*/
3536

3637
import java.io.*;
@@ -60,7 +61,6 @@
6061

6162
import sun.security.testlibrary.SimpleOCSPServer;
6263
import sun.security.testlibrary.CertificateBuilder;
63-
import sun.security.validator.ValidatorException;
6464

6565
public class HttpsUrlConnClient {
6666

@@ -73,6 +73,9 @@ public class HttpsUrlConnClient {
7373
static final byte[] LINESEP = { 10 };
7474
static final Base64.Encoder B64E = Base64.getMimeEncoder(64, LINESEP);
7575

76+
static String SIGALG;
77+
static String KEYALG;
78+
7679
// Turn on TLS debugging
7780
static boolean debug = true;
7881

@@ -137,6 +140,9 @@ public static void main(String[] args) throws Exception {
137140
System.setProperty("javax.net.ssl.trustStore", "");
138141
System.setProperty("javax.net.ssl.trustStorePassword", "");
139142

143+
KEYALG = args[0];
144+
SIGALG = args[1];
145+
140146
// Create the PKI we will use for the test and start the OCSP servers
141147
createPKI();
142148
utcDateFmt.setTimeZone(TimeZone.getTimeZone("GMT"));
@@ -514,7 +520,7 @@ public void run() {
514520
*/
515521
private static void createPKI() throws Exception {
516522
CertificateBuilder cbld = new CertificateBuilder();
517-
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
523+
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KEYALG);
518524
keyGen.initialize(2048);
519525
KeyStore.Builder keyStoreBuilder =
520526
KeyStore.Builder.newInstance("PKCS12", null,
@@ -540,7 +546,7 @@ private static void createPKI() throws Exception {
540546
addCommonCAExts(cbld);
541547
// Make our Root CA Cert!
542548
X509Certificate rootCert = cbld.build(null, rootCaKP.getPrivate(),
543-
"SHA256withRSA");
549+
SIGALG);
544550
log("Root CA Created:\n" + certInfo(rootCert));
545551

546552
// Now build a keystore and add the keys and cert
@@ -582,7 +588,7 @@ private static void createPKI() throws Exception {
582588
cbld.addAIAExt(Collections.singletonList(rootRespURI));
583589
// Make our Intermediate CA Cert!
584590
X509Certificate intCaCert = cbld.build(rootCert, rootCaKP.getPrivate(),
585-
"SHA256withRSA");
591+
SIGALG);
586592
log("Intermediate CA Created:\n" + certInfo(intCaCert));
587593

588594
// Provide intermediate CA cert revocation info to the Root CA
@@ -644,7 +650,7 @@ private static void createPKI() throws Exception {
644650
cbld.addAIAExt(Collections.singletonList(intCaRespURI));
645651
// Make our SSL Server Cert!
646652
X509Certificate sslCert = cbld.build(intCaCert, intCaKP.getPrivate(),
647-
"SHA256withRSA");
653+
SIGALG);
648654
log("SSL Certificate Created:\n" + certInfo(sslCert));
649655

650656
// Provide SSL server cert revocation info to the Intermeidate CA

0 commit comments

Comments
 (0)
Please sign in to comment.