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.util.LazyX509Certificate;
19 import org.jetbrains.annotations.Nullable;
20
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.nio.charset.StandardCharsets;
24 import java.security.cert.X509Certificate;
25
26 final class BoringSSL {
27
28 static final int SSL_VERIFY_NONE = BoringSSLNativeStaticallyReferencedJniMethods.ssl_verify_none();
29 static final int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = BoringSSLNativeStaticallyReferencedJniMethods
30 .ssl_verify_fail_if_no_peer_cert();
31 static final int SSL_VERIFY_PEER = BoringSSLNativeStaticallyReferencedJniMethods.ssl_verify_peer();
32 static final int X509_V_OK = BoringSSLNativeStaticallyReferencedJniMethods.x509_v_ok();
33 static final int X509_V_ERR_CERT_HAS_EXPIRED =
34 BoringSSLNativeStaticallyReferencedJniMethods.x509_v_err_cert_has_expired();
35 static final int X509_V_ERR_CERT_NOT_YET_VALID =
36 BoringSSLNativeStaticallyReferencedJniMethods.x509_v_err_cert_not_yet_valid();
37 static final int X509_V_ERR_CERT_REVOKED = BoringSSLNativeStaticallyReferencedJniMethods.x509_v_err_cert_revoked();
38 static final int X509_V_ERR_UNSPECIFIED = BoringSSLNativeStaticallyReferencedJniMethods.x509_v_err_unspecified();
39
40 static long SSLContext_new(boolean server, String[] applicationProtocols,
41 BoringSSLHandshakeCompleteCallback handshakeCompleteCallback,
42 BoringSSLCertificateCallback certificateCallback,
43 BoringSSLCertificateVerifyCallback verifyCallback,
44 @Nullable BoringSSLTlsextServernameCallback servernameCallback,
45 @Nullable BoringSSLKeylogCallback keylogCallback,
46 @Nullable BoringSSLSessionCallback sessionCallback,
47 @Nullable BoringSSLPrivateKeyMethod privateKeyMethod,
48 BoringSSLSessionTicketCallback sessionTicketCallback,
49 int verifyMode,
50 byte[][] subjectNames) {
51 return SSLContext_new0(server, toWireFormat(applicationProtocols),
52 handshakeCompleteCallback, certificateCallback, verifyCallback, servernameCallback,
53 keylogCallback, sessionCallback, privateKeyMethod, sessionTicketCallback, verifyMode, subjectNames);
54 }
55
56 private static byte @Nullable [] toWireFormat(String @Nullable [] applicationProtocols) {
57 if (applicationProtocols == null) {
58 return null;
59 }
60 try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
61 for (String p : applicationProtocols) {
62 byte[] bytes = p.getBytes(StandardCharsets.US_ASCII);
63 out.write(bytes.length);
64 out.write(bytes);
65 }
66 return out.toByteArray();
67 } catch (IOException e) {
68 throw new IllegalStateException(e);
69 }
70 }
71
72 static native long SSLContext_new();
73
74 private static native long SSLContext_new0(boolean server,
75 byte @Nullable [] applicationProtocols, Object handshakeCompleteCallback,
76 Object certificateCallback, Object verifyCallback,
77 @Nullable Object servernameCallback, @Nullable Object keylogCallback,
78 @Nullable Object sessionCallback,
79 @Nullable Object privateKeyMethod,
80 Object sessionTicketCallback,
81 int verifyDepth, byte[][] subjectNames);
82 static native void SSLContext_set_early_data_enabled(long context, boolean enabled);
83 static native long SSLContext_setSessionCacheSize(long context, long size);
84 static native long SSLContext_setSessionCacheTimeout(long context, long size);
85 static native boolean SSLContext_setSessionIdContext(long context, byte[] sidCtx);
86
87 static native void SSLContext_setSessionTicketKeys(long context, boolean enableCallback);
88
89 static int SSLContext_set1_groups_list(long ctx, String... groups) {
90 if (groups == null) {
91 throw new NullPointerException("curves");
92 }
93 if (groups.length == 0) {
94 throw new IllegalArgumentException();
95 }
96 StringBuilder sb = new StringBuilder();
97 for (String group: groups) {
98 sb.append(group);
99
100 sb.append(':');
101 }
102 sb.setLength(sb.length() - 1);
103 return SSLContext_set1_groups_list(ctx, sb.toString());
104 }
105
106 static int SSLContext_set1_sigalgs_list(long ctx, String... sigalgs) {
107 if (sigalgs.length == 0) {
108 throw new IllegalArgumentException();
109 }
110 StringBuilder sb = new StringBuilder();
111 for (String sigalg: sigalgs) {
112 sb.append(sigalg);
113
114 sb.append(':');
115 }
116 sb.setLength(sb.length() - 1);
117 return SSLContext_set1_sigalgs_list(ctx, sb.toString());
118 }
119
120 private static native int SSLContext_set1_sigalgs_list(long context, String sigalgs);
121
122 private static native int SSLContext_set1_groups_list(long context, String groups);
123 static native void SSLContext_free(long context);
124 static long SSL_new(long context, boolean server, String hostname) {
125 return SSL_new0(context, server, tlsExtHostName(hostname));
126 }
127 static native long SSL_new0(long context, boolean server, @Nullable String hostname);
128 static native void SSL_free(long ssl);
129
130 static native Runnable SSL_getTask(long ssl);
131
132 static native void SSL_cleanup(long ssl);
133
134 static native long EVP_PKEY_parse(byte[] bytes, String pass);
135 static native void EVP_PKEY_free(long key);
136
137 static native long CRYPTO_BUFFER_stack_new(long ssl, byte[][] bytes);
138 static native void CRYPTO_BUFFER_stack_free(long chain);
139
140 @Nullable
141 static native String ERR_last_error();
142
143 @Nullable
144 private static String tlsExtHostName(@Nullable String hostname) {
145 if (hostname != null && hostname.endsWith(".")) {
146
147
148 hostname = hostname.substring(0, hostname.length() - 1);
149 }
150 return hostname;
151 }
152
153 static X509Certificate[] certificates(byte[][] chain) {
154 X509Certificate[] peerCerts = new X509Certificate[chain.length];
155 for (int i = 0; i < peerCerts.length; i++) {
156 peerCerts[i] = new LazyX509Certificate(chain[i]);
157 }
158 return peerCerts;
159 }
160
161 static byte[][] subjectNames(X509Certificate[] certificates) {
162 byte[][] subjectNames = new byte[certificates.length][];
163 for (int i = 0; i < certificates.length; i++) {
164 subjectNames[i] = certificates[i].getSubjectX500Principal().getEncoded();
165 }
166 return subjectNames;
167 }
168
169 private BoringSSL() { }
170 }