Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple SSL Certificate Pinning #38

Open
ericgosno opened this issue Nov 4, 2018 · 4 comments
Open

Multiple SSL Certificate Pinning #38

ericgosno opened this issue Nov 4, 2018 · 4 comments

Comments

@ericgosno
Copy link

Hello,

I am aware that from the Readme, it already said that "Once you've enabled SSL pinning you CAN NOT re-enable with a different host or certificate file." which means that for now the SSL Pinning can only work for 1 certificates.

Is there any workaround to make it works on more than 1 certificate in case we need to do SSL Pinning on more than one API endpoint?

@ferryfw
Copy link

ferryfw commented Nov 5, 2018

Actually I got the same need in my current project. Is this feature even included somewhere in the roadmap? And for the meantime, can we work something to make it work? Anything to point us in the right direction is appreciated.

@jeffwhelpley
Copy link
Collaborator

Apologies to both of you. We are a small company and unfortunately we don't have time to update this library right now. However, we do want to resolve the outstanding issues and will get to this as soon as we can. In the meantime, if you wanted to submit a PR we would appreciate it.

@roblav96 are there any workarounds you can think of in the short term?

@facetious
Copy link

No Guarantees

Here's a patch that might work for you.

index a130232..0b368f1 100644
--- a/src/https.android.ts
+++ b/src/https.android.ts
@@ -27,18 +27,19 @@ interface Ipeer {
 	allowInvalidCertificates: boolean
 	validatesDomainName: boolean
 	host?: string
-	certificate?: string
+	certificates: string[]
 	x509Certificate?: java.security.cert.Certificate
 }
 let peer: Ipeer = {
 	enabled: false,
 	allowInvalidCertificates: false,
 	validatesDomainName: true,
+	certificates: [],
 }
 
 export function enableSSLPinning(options: Https.HttpsSSLPinningOptions) {
 	// console.log('options', options)
-	if (!peer.host && !peer.certificate) {
+	if (!peer.host) {
 		let certificate: string
 		let inputStream: java.io.FileInputStream
 		try {
@@ -58,7 +59,9 @@ export function enableSSLPinning(options: Https.HttpsSSLPinningOptions) {
 			return
 		}
 		peer.host = options.host
-		peer.certificate = certificate
+		if (peer.certificates.indexOf(certificate) === -1) {
+			peer.certificates.push(certificate)
+		}
 		if (options.allowInvalidCertificates == true) {
 			peer.allowInvalidCertificates = true
 		}
@@ -72,6 +75,8 @@ export function enableSSLPinning(options: Https.HttpsSSLPinningOptions) {
 }
 export function disableSSLPinning() {
 	peer.enabled = false
+	peer.certificates.length = 0;
+	getClient(true)
 	getClient(true)
 	console.log('nativescript-https > Disabled SSL pinning')
 }
@@ -100,7 +105,7 @@ function getClient(reload: boolean = false): okhttp3.OkHttpClient {
 			client.connectionSpecs(java.util.Collections.singletonList(spec))
 
 			let pinner = new okhttp3.CertificatePinner.Builder()
-			pinner.add(peer.host, [peer.certificate])
+			pinner.add(peer.host, peer.certificates)
 			client.certificatePinner(pinner.build())
 
 			if (peer.allowInvalidCertificates == false) {
diff --git a/src/https.ios.ts b/src/https.ios.ts
index aed1bf9..2bb0c92 100644
--- a/src/https.ios.ts
+++ b/src/https.ios.ts
@@ -17,6 +17,7 @@ let policies: Ipolicies = {
 }
 policies.def.allowInvalidCertificates = true
 policies.def.validatesDomainName = false
+let certificates: NSData[] = [];
 
 export function enableSSLPinning(options: Https.HttpsSSLPinningOptions) {
 	// console.log('options', options)
@@ -26,12 +27,12 @@ export function enableSSLPinning(options: Https.HttpsSSLPinningOptions) {
 		policies.secure.allowInvalidCertificates = allowInvalidCertificates
 		let validatesDomainName = (isDefined(options.validatesDomainName)) ? options.validatesDomainName : true
 		policies.secure.validatesDomainName = validatesDomainName
-		let data = NSData.dataWithContentsOfFile(options.certificate)
+		certificates.push(NSData.dataWithContentsOfFile(options.certificate))
 		// console.log('data.description', data.description)
 		// console.log('data.bytes', data.bytes)
 		// console.log('data.base64Encoding()', data.base64Encoding())
 		// console.log('data.length', data.length)
-		policies.secure.pinnedCertificates = NSSet.setWithObject(data)
+		policies.secure.pinnedCertificates = NSSet.setWithArray(certificates)
 	}
 	policies.secured = true
 	console.log('nativescript-https > Enabled SSL pinning')

@adambeck7
Copy link

Was there ever an official fix for this? Has anyone gotten the above patch to work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants