Created
October 30, 2019 17:55
-
-
Save coreequip/8788fd21a677aa8e6fb3e5222ec0c1ef to your computer and use it in GitHub Desktop.
Simple certificate pinning in groovy.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package dev.coreequip.security | |
import javax.net.ssl.HttpsURLConnection | |
import javax.net.ssl.SSLContext | |
import javax.net.ssl.TrustManager | |
import javax.net.ssl.X509TrustManager | |
import java.security.MessageDigest | |
import java.security.cert.CertificateException | |
import java.security.cert.X509Certificate | |
/** | |
* A TrustManager that only allows certificates thats pinned. | |
* All others are rejected.<br> | |
* <br> | |
* Usage: <tt>PinningTrustManager.init(certificatePublicKeyHash)</tt> | |
*/ | |
class PinningTrustManager { | |
static pins = [] as Set | |
/** | |
* Init TrustManager with no pins. | |
*/ | |
static void init() { | |
def pinningManager = [ | |
getAcceptedIssuers: {}, | |
checkClientTrusted: { a, b -> }, | |
checkServerTrusted: { X509Certificate[] chain, String authType -> | |
for (X509Certificate cert : chain) { | |
def hash = new BigInteger(1, | |
MessageDigest.getInstance('SHA-256').digest(cert.publicKey.encoded) | |
).toString(16).padLeft(64, '0').toLowerCase() | |
if (pins.contains(hash)) return | |
} | |
throw new CertificateException('None of these certificates are pinned.') | |
} | |
] as X509TrustManager | |
def sslContext = SSLContext.getInstance('TLS') | |
sslContext.init(null, [pinningManager] as TrustManager[], null) | |
SSLContext.setDefault(sslContext) | |
} | |
/** | |
* Init TrustManager with a pin. | |
* | |
* @param pin Hexadecimal representation of pinned certificate's public key | |
*/ | |
static void init(String pin) { | |
pins.add(pin.toLowerCase()) | |
init() | |
} | |
/** | |
* Add a pin the TrustManager. | |
* | |
* @param pin Hexadecimal representation of pinned certificate's public key | |
*/ | |
static void addPin(String pin) { | |
pins.add(pin) | |
} | |
static void main(String[] args) { | |
init('451335746aa70c5b022570531e4cb5eaf8b5a1b3a50a01459ffc8e848ff2fa1a') | |
try { | |
def con = 'https://github.com'.toURL().openConnection() as HttpsURLConnection | |
con.connect() | |
} catch (Exception e) { | |
e.printStackTrace() | |
} | |
println 'Done.' | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment