25
25
26
26
import java .io .*;
27
27
import java .net .*;
28
+ import java .nio .charset .StandardCharsets ;
28
29
import java .security .*;
29
30
import java .security .cert .CRLReason ;
30
31
import java .security .cert .X509Certificate ;
@@ -61,22 +62,22 @@ public class SimpleOCSPServer {
61
62
static final int FREE_PORT = 0 ;
62
63
63
64
// CertStatus values
64
- public static enum CertStatus {
65
+ public enum CertStatus {
65
66
CERT_STATUS_GOOD ,
66
67
CERT_STATUS_REVOKED ,
67
68
CERT_STATUS_UNKNOWN ,
68
69
}
69
70
70
71
// Fields used for the networking portion of the responder
71
72
private ServerSocket servSocket ;
72
- private InetAddress listenAddress ;
73
+ private final InetAddress listenAddress ;
73
74
private int listenPort ;
74
75
75
76
// Keystore information (certs, keys, etc.)
76
- private KeyStore keystore ;
77
- private X509Certificate issuerCert ;
78
- private X509Certificate signerCert ;
79
- private PrivateKey signerKey ;
77
+ private final KeyStore keystore ;
78
+ private final X509Certificate issuerCert ;
79
+ private final X509Certificate signerCert ;
80
+ private final PrivateKey signerKey ;
80
81
81
82
// Fields used for the operational portions of the server
82
83
private boolean logEnabled = false ;
@@ -91,9 +92,9 @@ public static enum CertStatus {
91
92
// Fields used in the generation of responses
92
93
private long nextUpdateInterval = -1 ;
93
94
private Date nextUpdate = null ;
94
- private ResponderId respId ;
95
- private AlgorithmId sigAlgId ;
96
- private Map <CertId , CertStatusInfo > statusDb =
95
+ private final ResponderId respId ;
96
+ private String sigAlgName ;
97
+ private final Map <CertId , CertStatusInfo > statusDb =
97
98
Collections .synchronizedMap (new HashMap <>());
98
99
99
100
/**
@@ -140,40 +141,39 @@ public SimpleOCSPServer(KeyStore ks, String password, String issuerAlias,
140
141
public SimpleOCSPServer (InetAddress addr , int port , KeyStore ks ,
141
142
String password , String issuerAlias , String signerAlias )
142
143
throws GeneralSecurityException , IOException {
143
- Objects .requireNonNull (ks , "Null keystore provided" );
144
+ keystore = Objects .requireNonNull (ks , "Null keystore provided" );
144
145
Objects .requireNonNull (issuerAlias , "Null issuerName provided" );
145
146
146
147
utcDateFmt .setTimeZone (TimeZone .getTimeZone ("GMT" ));
147
148
148
- keystore = ks ;
149
- issuerCert = (X509Certificate )ks .getCertificate (issuerAlias );
149
+ issuerCert = (X509Certificate )keystore .getCertificate (issuerAlias );
150
150
if (issuerCert == null ) {
151
151
throw new IllegalArgumentException ("Certificate for alias " +
152
152
issuerAlias + " not found" );
153
153
}
154
154
155
155
if (signerAlias != null ) {
156
- signerCert = (X509Certificate )ks .getCertificate (signerAlias );
156
+ signerCert = (X509Certificate )keystore .getCertificate (signerAlias );
157
157
if (signerCert == null ) {
158
158
throw new IllegalArgumentException ("Certificate for alias " +
159
159
signerAlias + " not found" );
160
160
}
161
- signerKey = (PrivateKey )ks .getKey (signerAlias ,
161
+ signerKey = (PrivateKey )keystore .getKey (signerAlias ,
162
162
password .toCharArray ());
163
163
if (signerKey == null ) {
164
164
throw new IllegalArgumentException ("PrivateKey for alias " +
165
165
signerAlias + " not found" );
166
166
}
167
167
} else {
168
168
signerCert = issuerCert ;
169
- signerKey = (PrivateKey )ks .getKey (issuerAlias ,
169
+ signerKey = (PrivateKey )keystore .getKey (issuerAlias ,
170
170
password .toCharArray ());
171
171
if (signerKey == null ) {
172
172
throw new IllegalArgumentException ("PrivateKey for alias " +
173
173
issuerAlias + " not found" );
174
174
}
175
175
}
176
- sigAlgId = AlgorithmId . get ( SignatureUtil .getDefaultSigAlgForKey (signerKey ) );
176
+ sigAlgName = SignatureUtil .getDefaultSigAlgForKey (signerKey );
177
177
respId = new ResponderId (signerCert .getSubjectX500Principal ());
178
178
listenAddress = addr ;
179
179
listenPort = port ;
@@ -495,8 +495,14 @@ private Map<CertId, CertStatusInfo> checkStatusDb(
495
495
public void setSignatureAlgorithm (String algName )
496
496
throws NoSuchAlgorithmException {
497
497
if (!started ) {
498
- sigAlgId = AlgorithmId .get (algName );
499
- log ("Signature algorithm set to " + sigAlgId .getName ());
498
+ // We don't care about the AlgorithmId object, we're just
499
+ // using it to validate the algName parameter.
500
+ AlgorithmId .get (algName );
501
+ sigAlgName = algName ;
502
+ log ("Signature algorithm set to " + algName );
503
+ } else {
504
+ log ("Signature algorithm cannot be set on a running server, " +
505
+ "stop the server first" );
500
506
}
501
507
}
502
508
@@ -604,9 +610,9 @@ private static synchronized void err(Throwable exc) {
604
610
* object may be used to construct OCSP responses.
605
611
*/
606
612
public static class CertStatusInfo {
607
- private CertStatus certStatusType ;
613
+ private final CertStatus certStatusType ;
608
614
private CRLReason reason ;
609
- private Date revocationTime ;
615
+ private final Date revocationTime ;
610
616
611
617
/**
612
618
* Create a Certificate status object by providing the status only.
@@ -745,7 +751,7 @@ public void run() {
745
751
// This will be tokenized so we know if we are dealing with
746
752
// a GET or POST.
747
753
String [] headerTokens = readLine (in ).split (" " );
748
- LocalOcspRequest ocspReq = null ;
754
+ LocalOcspRequest ocspReq ;
749
755
LocalOcspResponse ocspResp = null ;
750
756
ResponseStatus respStat = ResponseStatus .INTERNAL_ERROR ;
751
757
try {
@@ -794,7 +800,7 @@ public void run() {
794
800
out .flush ();
795
801
796
802
log ("Closing " + ocspSocket );
797
- } catch (IOException | CertificateException exc ) {
803
+ } catch (IOException | GeneralSecurityException exc ) {
798
804
err (exc );
799
805
}
800
806
}
@@ -826,10 +832,10 @@ public void sendResponse(OutputStream out, LocalOcspResponse resp)
826
832
append ("\r \n " );
827
833
}
828
834
sb .append ("\r \n " );
835
+ log (resp .toString ());
829
836
830
- out .write (sb .toString ().getBytes ("UTF-8" ));
837
+ out .write (sb .toString ().getBytes (StandardCharsets . UTF_8 ));
831
838
out .write (respBytes );
832
- log (resp .toString ());
833
839
}
834
840
835
841
/**
@@ -940,7 +946,7 @@ private LocalOcspRequest parseHttpOcspGet(String[] headerTokens,
940
946
// "/" off before decoding.
941
947
return new LocalOcspRequest (Base64 .getMimeDecoder ().decode (
942
948
URLDecoder .decode (headerTokens [1 ].replaceAll ("/" , "" ),
943
- "UTF-8" )));
949
+ StandardCharsets . UTF_8 )));
944
950
}
945
951
946
952
/**
@@ -974,8 +980,7 @@ private String readLine(InputStream is) throws IOException {
974
980
bos .write (b );
975
981
}
976
982
}
977
-
978
- return new String (bos .toByteArray (), "UTF-8" );
983
+ return bos .toString (StandardCharsets .UTF_8 );
979
984
}
980
985
}
981
986
@@ -1052,7 +1057,6 @@ private void parseSignature(DerValue sigSequence)
1052
1057
1053
1058
if (sigItems [2 ].isContextSpecific ((byte )0 )) {
1054
1059
DerValue [] certDerItems = sigItems [2 ].data .getSequence (4 );
1055
- int i = 0 ;
1056
1060
for (DerValue dv : certDerItems ) {
1057
1061
X509Certificate xc = new X509CertImpl (dv );
1058
1062
certificates .add (xc );
@@ -1131,7 +1135,7 @@ private List<LocalSingleRequest> getRequests() {
1131
1135
* Return the list of X.509 Certificates in this OCSP request.
1132
1136
*
1133
1137
* @return an unmodifiable {@code List} of zero or more
1134
- * {@cpde X509Certificate} objects.
1138
+ * {@code X509Certificate} objects.
1135
1139
*/
1136
1140
private List <X509Certificate > getCertificates () {
1137
1141
return Collections .unmodifiableList (certificates );
@@ -1295,7 +1299,8 @@ public class LocalOcspResponse {
1295
1299
private final Map <String , Extension > responseExtensions ;
1296
1300
private byte [] signature ;
1297
1301
private final List <X509Certificate > certificates ;
1298
- private final byte [] encodedResponse ;
1302
+ private final Signature signEngine ;
1303
+ private final AlgorithmId sigAlgId ;
1299
1304
1300
1305
/**
1301
1306
* Constructor for the generation of non-successful responses
@@ -1305,9 +1310,11 @@ public class LocalOcspResponse {
1305
1310
* @throws IOException if an error happens during encoding
1306
1311
* @throws NullPointerException if {@code respStat} is {@code null}
1307
1312
* or {@code respStat} is successful.
1313
+ * @throws GeneralSecurityException if errors occur while obtaining
1314
+ * the signature object or any algorithm identifier parameters.
1308
1315
*/
1309
1316
public LocalOcspResponse (OCSPResponse .ResponseStatus respStat )
1310
- throws IOException {
1317
+ throws IOException , GeneralSecurityException {
1311
1318
this (respStat , null , null );
1312
1319
}
1313
1320
@@ -1324,10 +1331,13 @@ public LocalOcspResponse(OCSPResponse.ResponseStatus respStat)
1324
1331
* @throws NullPointerException if {@code respStat} is {@code null}
1325
1332
* or {@code respStat} is successful, and a {@code null} {@code itemMap}
1326
1333
* has been provided.
1334
+ * @throws GeneralSecurityException if errors occur while obtaining
1335
+ * the signature object or any algorithm identifier parameters.
1327
1336
*/
1328
1337
public LocalOcspResponse (OCSPResponse .ResponseStatus respStat ,
1329
1338
Map <CertId , CertStatusInfo > itemMap ,
1330
- Map <String , Extension > reqExtensions ) throws IOException {
1339
+ Map <String , Extension > reqExtensions )
1340
+ throws IOException , GeneralSecurityException {
1331
1341
responseStatus = Objects .requireNonNull (respStat ,
1332
1342
"Illegal null response status" );
1333
1343
if (responseStatus == ResponseStatus .SUCCESSFUL ) {
@@ -1348,13 +1358,18 @@ public LocalOcspResponse(OCSPResponse.ResponseStatus respStat,
1348
1358
certificates .add (signerCert );
1349
1359
}
1350
1360
certificates .add (issuerCert );
1361
+ // Create the signature object and AlgorithmId that we'll use
1362
+ // later to create the signature on this response.
1363
+ signEngine = SignatureUtil .fromKey (sigAlgName , signerKey , "" );
1364
+ sigAlgId = SignatureUtil .fromSignature (signEngine , signerKey );
1351
1365
} else {
1352
1366
respItemMap = null ;
1353
1367
producedAtDate = null ;
1354
1368
responseExtensions = null ;
1355
1369
certificates = null ;
1370
+ signEngine = null ;
1371
+ sigAlgId = null ;
1356
1372
}
1357
- encodedResponse = this .getBytes ();
1358
1373
}
1359
1374
1360
1375
/**
@@ -1436,13 +1451,9 @@ private byte[] encodeBasicOcspResponse() throws IOException {
1436
1451
basicORItemStream .write (tbsResponseBytes );
1437
1452
1438
1453
try {
1439
- // Create the signature
1440
- Signature sig = SignatureUtil .fromKey (
1441
- sigAlgId .getName (), signerKey , (Provider )null );
1442
- sig .update (tbsResponseBytes );
1443
- signature = sig .sign ();
1444
- // Rewrite signAlg, RSASSA-PSS needs some parameters.
1445
- sigAlgId = SignatureUtil .fromSignature (sig , signerKey );
1454
+ // Create the signature with the initialized Signature object
1455
+ signEngine .update (tbsResponseBytes );
1456
+ signature = signEngine .sign ();
1446
1457
sigAlgId .encode (basicORItemStream );
1447
1458
basicORItemStream .putBitString (signature );
1448
1459
} catch (GeneralSecurityException exc ) {
1 commit comments
openjdk-notifier[bot] commentedon Feb 21, 2025
Review
Issues