From 70e6ef0fc6afecbdfac0597dc2a3bbff1f057ee4 Mon Sep 17 00:00:00 2001 From: zhengjw22 Date: Sat, 9 Nov 2024 15:23:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/SecurityProviderImpl.java | 67 +++++++++++++++++-- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/plugins/security/SecurityProviderImpl.java b/servlet-core/src/main/java/tech/smartboot/servlet/plugins/security/SecurityProviderImpl.java index aedfc5a..7548d58 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/plugins/security/SecurityProviderImpl.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/plugins/security/SecurityProviderImpl.java @@ -149,14 +149,22 @@ private LoginAccount login(SmartHttpServletRequest request, HttpServletResponse // } } if (loginConfig != null && "CLIENT-CERT".equals(loginConfig.getAuthMethod())) { + List certificates = new ArrayList<>(); for (Certificate certificate : request.getSslEngine().getSession().getPeerCertificates()) { if (certificate instanceof X509Certificate) { - String name = ((X509Certificate) certificate).getIssuerX500Principal().getName(); - LoginAccount account = new LoginAccount(((X509Certificate) certificate).getIssuerX500Principal().getName(), null, securityRoleMapping.get(name), HttpServletRequest.CLIENT_CERT_AUTH); - request.setLoginAccount(account); - return account; + certificates.add((X509Certificate) certificate); } } + X509Certificate certificate = certificates.get(0); + String name = certificate.getIssuerX500Principal().getName(); + LoginAccount account = new LoginAccount(certificate.getIssuerX500Principal().getName(), null, securityRoleMapping.get(name), HttpServletRequest.CLIENT_CERT_AUTH); + request.setLoginAccount(account); + request.setAttribute("jakarta.servlet.request.X509Certificate", certificates.toArray(new X509Certificate[certificates.size()])); + request.setAttribute("jakarta.servlet.request.cipher_suite", request.getSslEngine().getSession().getCipherSuite()); + request.setAttribute("jakarta.servlet.request.key_size", calculateKeySize(request.getSslEngine().getSession().getCipherSuite())); + byte[] sessionId = request.getSslEngine().getSession().getId(); + request.setAttribute("jakarta.servlet.request.ssl_session_id", sessionId != null ? convertToHexString(sessionId) : null); + return account; } else { } @@ -254,4 +262,55 @@ private boolean check(SmartHttpServletRequest request, HttpServletResponse respo } return true; } + + static int calculateKeySize(String cipherSuite) { + // Roughly ordered from most common to least common. + if (cipherSuite == null) { + return 0; + // TLS 1.3: https://wiki.openssl.org/index.php/TLS1.3 + } else if (cipherSuite.equals("TLS_AES_256_GCM_SHA384")) { + return 256; + } else if (cipherSuite.equals("TLS_CHACHA20_POLY1305_SHA256")) { + return 256; + } else if (cipherSuite.startsWith("TLS_AES_128_")) { + return 128; + // TLS <1.3 + } else if (cipherSuite.contains("WITH_AES_128_")) { + return 128; + } else if (cipherSuite.contains("WITH_AES_256_")) { + return 256; + } else if (cipherSuite.contains("WITH_3DES_EDE_CBC_")) { + return 168; + } else if (cipherSuite.contains("WITH_RC4_128_")) { + return 128; + } else if (cipherSuite.contains("WITH_DES_CBC_")) { + return 56; + } else if (cipherSuite.contains("WITH_DES40_CBC_")) { + return 40; + } else if (cipherSuite.contains("WITH_RC4_40_")) { + return 40; + } else if (cipherSuite.contains("WITH_IDEA_CBC_")) { + return 128; + } else if (cipherSuite.contains("WITH_RC2_CBC_40_")) { + return 40; + } else { + return 0; + } + } + + private static final char[] HEX_CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + private static final byte[] HEX_BYTES = new byte[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + public static String convertToHexString(byte[] toBeConverted) { + + char[] converted = new char[toBeConverted.length * 2]; + for (int i = 0; i < toBeConverted.length; i++) { + byte b = toBeConverted[i]; + converted[i * 2] = HEX_CHARS[b >> 4 & 0x0F]; + converted[i * 2 + 1] = HEX_CHARS[b & 0x0F]; + } + + return String.valueOf(converted); + } }