Skip to content

Commit efcd7c0

Browse files
author
kasemir
committed
OCSP: Check key, name hash and serial to confirm "ID"
1 parent f59456e commit efcd7c0

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

core/pva/src/main/java/org/epics/pva/common/CertificateStatus.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import static org.epics.pva.PVASettings.logger;
1111

12+
import java.security.MessageDigest;
1213
import java.security.cert.X509Certificate;
1314
import java.util.Arrays;
1415
import java.util.BitSet;
@@ -141,7 +142,8 @@ private void handleMonitor(final PVAChannel channel, final BitSet changes, final
141142
for (X509Certificate x509 : SecureSockets.keychain_x509_certificates.values())
142143
if (basic.isSignatureValid(new JcaContentVerifierProviderBuilder().build(x509)))
143144
{
144-
logger.log(Level.FINER, () -> "OCSP response verified by " + x509.getSubjectX500Principal());
145+
logger.log(Level.FINER, () -> "OCSP response verified by trusted certificate for " +
146+
x509.getSubjectX500Principal());
145147
valid = true;
146148
break;
147149
}
@@ -159,22 +161,42 @@ private void handleMonitor(final PVAChannel channel, final BitSet changes, final
159161
for (SingleResp response : basic.getResponses())
160162
{
161163
// Is response for the certificate we want to check?
162-
// Same authority?
163164
final CertificateID id = response.getCertID();
165+
166+
// 1) Same authority name (only have hash of name)?
167+
// When last checked, hash_alg was "1.3.14.3.2.26" = SHA-1
168+
final String hash_alg = id.getHashAlgOID().getId();
169+
final MessageDigest digest = MessageDigest.getInstance(hash_alg);
170+
final byte[] cert_issuer_name_hash = digest.digest(bc_cert.getIssuer().getEncoded());
171+
if (! Arrays.equals(cert_issuer_name_hash, id.getIssuerNameHash()))
172+
{
173+
logger.log(Level.FINER, () -> "OCSP authority hash for name " + certificate.getIssuerX500Principal() +
174+
"\n" + Hexdump.toHexdump(id.getIssuerNameHash()) +
175+
"\ndiffers from expected\n" + Hexdump.toHexdump(cert_issuer_name_hash));
176+
continue;
177+
}
178+
logger.log(Level.FINER, () -> "OCSP authority hash for name " + certificate.getIssuerX500Principal() +
179+
"\n" + Hexdump.toHexdump(id.getIssuerNameHash()));
180+
181+
// 2) Same authority key?
164182
if (! Arrays.equals(authority_key_id, id.getIssuerKeyHash()))
165183
{
166-
logger.log(Level.FINER, () -> "OCSP authority\n" + Hexdump.toHexdump(id.getIssuerKeyHash()) +
167-
"\ndiffers from\n" + Hexdump.toHexdump(authority_key_id));
184+
logger.log(Level.FINER, () -> "OCSP authority key\n" + Hexdump.toHexdump(id.getIssuerKeyHash()) +
185+
"\ndiffers from expected\n" + Hexdump.toHexdump(authority_key_id));
168186
continue;
169187
}
188+
logger.log(Level.FINER, () -> "OCSP authority key\n" + Hexdump.toHexdump(id.getIssuerKeyHash()));
170189

171-
// Same serial number?
190+
// 3) Same serial number?
172191
if (! id.getSerialNumber().equals(certificate.getSerialNumber()))
173192
{
174-
logger.log(Level.FINER, () -> "OCSP Serial: 0x" + id.getSerialNumber().toString(16) +
193+
logger.log(Level.FINER, () -> "OCSP serial 0x" + id.getSerialNumber().toString(16) +
175194
" differs from expected 0x" + certificate.getSerialNumber().toString(16));
176195
continue;
177196
}
197+
logger.log(Level.FINER, () -> "OCSP Serial: 0x" + id.getSerialNumber().toString(16));
198+
199+
// Response seems applicable to the certificate we want to check!
178200

179201
// Is covered time range from <= now <= until? 'until' may be null...
180202
final Date now = new Date(), from = response.getThisUpdate(), until = response.getNextUpdate();
@@ -185,8 +207,6 @@ private void handleMonitor(final PVAChannel channel, final BitSet changes, final
185207
continue;
186208
}
187209

188-
// Seems applicable to the certificate we want to check.
189-
190210
// What is the status? OCSP only indicates null for valid, RevokedStatus with revocation date, or UnknownStatus.
191211
// Use that to potentially correct the more detailed status from the enum
192212
final org.bouncycastle.cert.ocsp.CertificateStatus response_status = response.getCertStatus();

0 commit comments

Comments
 (0)