1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.quic;
17
18 import io.netty.handler.ssl.OpenSslCertificateException;
19 import org.jetbrains.annotations.Nullable;
20
21 import javax.net.ssl.X509ExtendedTrustManager;
22 import javax.net.ssl.X509TrustManager;
23 import java.security.cert.CertPathValidatorException;
24 import java.security.cert.CertificateExpiredException;
25 import java.security.cert.CertificateNotYetValidException;
26 import java.security.cert.CertificateRevokedException;
27 import java.security.cert.X509Certificate;
28
29 final class BoringSSLCertificateVerifyCallback {
30
31 private final QuicheQuicSslEngineMap engineMap;
32 private final X509TrustManager manager;
33
34 BoringSSLCertificateVerifyCallback(QuicheQuicSslEngineMap engineMap, @Nullable X509TrustManager manager) {
35 this.engineMap = engineMap;
36 this.manager = manager;
37 }
38
39 @SuppressWarnings("unused")
40 int verify(long ssl, byte[][] x509, String authAlgorithm) {
41 final QuicheQuicSslEngine engine = engineMap.get(ssl);
42 if (engine == null) {
43
44 return BoringSSL.X509_V_ERR_UNSPECIFIED;
45 }
46
47 if (manager == null) {
48 engineMap.remove(ssl);
49 return BoringSSL.X509_V_ERR_UNSPECIFIED;
50 }
51
52 X509Certificate[] peerCerts = BoringSSL.certificates(x509);
53 try {
54 if (engine.getUseClientMode()) {
55 if (manager instanceof X509ExtendedTrustManager) {
56 ((X509ExtendedTrustManager) manager).checkServerTrusted(peerCerts, authAlgorithm, engine);
57 } else {
58 manager.checkServerTrusted(peerCerts, authAlgorithm);
59 }
60 } else {
61 if (manager instanceof X509ExtendedTrustManager) {
62 ((X509ExtendedTrustManager) manager).checkClientTrusted(peerCerts, authAlgorithm, engine);
63 } else {
64 manager.checkClientTrusted(peerCerts, authAlgorithm);
65 }
66 }
67 return BoringSSL.X509_V_OK;
68 } catch (Throwable cause) {
69 engineMap.remove(ssl);
70
71 if (cause instanceof OpenSslCertificateException) {
72
73
74 return ((OpenSslCertificateException) cause).errorCode();
75 }
76 if (cause instanceof CertificateExpiredException) {
77 return BoringSSL.X509_V_ERR_CERT_HAS_EXPIRED;
78 }
79 if (cause instanceof CertificateNotYetValidException) {
80 return BoringSSL.X509_V_ERR_CERT_NOT_YET_VALID;
81 }
82 return translateToError(cause);
83 }
84 }
85
86 private static int translateToError(Throwable cause) {
87 if (cause instanceof CertificateRevokedException) {
88 return BoringSSL.X509_V_ERR_CERT_REVOKED;
89 }
90
91
92
93
94 Throwable wrapped = cause.getCause();
95 while (wrapped != null) {
96 if (wrapped instanceof CertPathValidatorException) {
97 CertPathValidatorException ex = (CertPathValidatorException) wrapped;
98 CertPathValidatorException.Reason reason = ex.getReason();
99 if (reason == CertPathValidatorException.BasicReason.EXPIRED) {
100 return BoringSSL.X509_V_ERR_CERT_HAS_EXPIRED;
101 }
102 if (reason == CertPathValidatorException.BasicReason.NOT_YET_VALID) {
103 return BoringSSL.X509_V_ERR_CERT_NOT_YET_VALID;
104 }
105 if (reason == CertPathValidatorException.BasicReason.REVOKED) {
106 return BoringSSL.X509_V_ERR_CERT_REVOKED;
107 }
108 }
109 wrapped = wrapped.getCause();
110 }
111 return BoringSSL.X509_V_ERR_UNSPECIFIED;
112 }
113 }