nativescript-community / https

Secure HTTP client with SSL pinning for Nativescript - iOS/Android
https://nativescript-community.github.io/https/
Other
50 stars 42 forks source link

JS: Https.request error javax.net.ssl.SSLPeerUnverifiedException: Hostname XX.XXX.XX.XX not verified: #32

Open 2adi opened 6 years ago

2adi commented 6 years ago

I have a big problem in my code, In https.androif.js I have :

"use strict";
var peer = {
    enabled: false,
    allowInvalidCertificates: false,
    validatesDomainName: true,
};
function enableSSLPinning(options) {
     if (!peer.host && !peer.certificate
    ) {
        var certificate = void 0;
        var InputSteram = void 0;

        try {
             var file = new java.io.file((options.certificate));
             inputstream = new java.io.fileinputstream(file);
             var x509certificate = java.security.cert.certificatefactory.getinstance('x509').generatecertificate(inputstream);
             peer.x509certificate = x509certificate;
             certificate = okhttp3.certificatepinner.pin(x509certificate);
             inputstream.close();
        }
        catch (error) {
            try {
                if (inputStream) {
                    console.log('inputStream', inputStream)
                    inputStream.close();
                }
            }
            catch (e) { }
            console.error('nativescript-https > enableSSLPinning error', error);
            return;
        }
        peer.host = options.host;
        peer.certificate = certificate;
        if (options.allowInvalidCertificates == true) {
            peer.allowInvalidCertificates = true;
        }
        if (options.validatesDomainName == false) {
            peer.validatesDomainName = false;
        }
    }
    peer.enabled = true;
    getClient(true);
    console.log('nativescript-https > Enabled SSL pinning');
}

exports.enableSSLPinning = enableSSLPinning;

function disableSSLPinning() {
    peer.enabled = false;
    getClient(true);
    console.log('nativescript-https > Disabled SSL pinning');
}

exports.disableSSLPinning = disableSSLPinning;
console.info('nativescript-https > Disabled SSL pinning by default');
var Client;
function getClient(reload) {
    console.log(reload)
    if (reload === void 0) { reload = false; }
    if (Client && reload == false) {
        return Client;
    }
    var client = new okhttp3.OkHttpClient.Builder();
    if (peer.enabled == true) {
        if (peer.host || peer.certificate) {
            var spec = okhttp3.ConnectionSpec.MODERN_TLS;
            client.connectionSpecs(java.util.Collections.singletonList(spec));
            var pinner = new okhttp3.CertificatePinner.Builder();
            pinner.add(peer.host, [peer.certificate]);
            client.certificatePinner(pinner.build());
            if (peer.allowInvalidCertificates == true) {
                try {
                    var x509Certificate = peer.x509Certificate;
                    var keyStore = java.security.KeyStore.getInstance(java.security.KeyStore.getDefaultType());
                    keyStore.load(null, null);
                    keyStore.setCertificateEntry('CA', x509Certificate);
                    var keyManagerFactory = javax.net.ssl.KeyManagerFactory.getInstance('X509');
                    keyManagerFactory.init(keyStore, null);
                    var keyManagers = keyManagerFactory.getKeyManagers();
                    var trustManagerFactory = javax.net.ssl.TrustManagerFactory.getInstance(javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm());
                    trustManagerFactory.init(keyStore);
                    var sslContext = javax.net.ssl.SSLContext.getInstance('TLS');
                    sslContext.init(keyManagers, trustManagerFactory.getTrustManagers(), new java.security.SecureRandom());
                    client.sslSocketFactory(sslContext.getSocketFactory());
                }
                catch (error) {
                    console.error('nativescript-https > client.allowInvalidCertificates error', error);
                }
            }
            if (peer.validatesDomainName == false) {
                try {
                    client.hostnameVerifier(new javax.net.ssl.HostnameVerifier({
                        verify: function (hostname, session) {
                            var pp = session.getPeerPrincipal().getName();
                            var hv = javax.net.ssl.HttpsURLConnection.getDefaultHostnameVerifier();
                            return (hv.verify(peer.host, session) &&
                                peer.host == hostname &&
                                peer.host == session.getPeerHost() &&
                                pp.indexOf(peer.host) != -1);
                        },
                    }));
                }
                catch (error) {
                    console.error('nativescript-https > client.validatesDomainName error', error);
                }
            }
        }
        else {
            console.warn('nativescript-https > Undefined host or certificate. SSL pinning NOT working!!!');
        }
    }
    Client = client.build();
    console.log('Client', Client)
    return Client;
}
function request(opts) {
    return new Promise(function (resolve, reject) {
        try {
            var client = getClient();
            var request_1 = new okhttp3.Request.Builder();
            request_1.url(opts.url);
            var reqheads_1 = opts.headers;
            Object.keys(reqheads_1).forEach(function (key) {
                request_1.addHeader(key, reqheads_1[key]);
            });
            if (opts.method == 'GET') {
                request_1.get();
            }
            else if (opts.method == 'POST') {
                var type = okhttp3.MediaType.parse('application/json');
                var body = okhttp3.RequestBody.create(type, opts.content);
                request_1.post(body);
            }
            client.newCall(request_1.build()).enqueue(new okhttp3.Callback({
                onResponse: function (task, response) {
                    var content;
                    try {
                        content = JSON.parse(response.body().string());
                    }
                    catch (error) {
                        return reject(error);
                    }
                    var statusCode = response.code();
                    var headers = {};
                    var heads = response.headers();
                    var i, len = heads.size();
                    for (i = 0; i < len; i++) {
                        var key = heads.name(i);
                        var value = heads.value(i);
                        headers[key] = value;
                    }
                    resolve({ content: content, statusCode: statusCode, headers: headers });
                },
                onFailure: function (task, error) {
                    reject(error);
                },
            }));
        }
        catch (error) {
            reject(error);
        }
    });
}
exports.request = request;

in component.ts I used this code:

let dir = knownFolders.currentApp().getFolder('certificate')
     let certificate = dir.getFile('certificate.pem').path
  Https.enableSSLPinning({ host: 'XX.XXX.XX.XX', certificate, allowInvalidCertificates: true, validatesDomainName: false })
    Https.request({
        url: 'https://XX.XXX.XX.XX:3333/login',
        method: 'GET',
        headers: {
            "Content-type": "application/x-www-form-urlencoded",
        },
    }).then(function (response) {
        console.log('Https.request response', response);
    }).catch(function (error) {
        console.error('Https.request error', error);
    })

I used self signed certificate that generate from server. I want to

allowInvalidCertificates: true, 
validatesDomainName: false 

From this code I get error:

JS: Https.request error javax.net.ssl.SSLPeerUnverifiedException: Hostname XX.XXX.XX.XX not verified:
JS: certificate: sha256/hfR9N2GN2WS1NQuHAAnOUc1gVQCf4f4HrhdlfXXP+Ko=
JS: DN: 1.2.840.113549.1.9.1=#16111315727473401578616d706c652e636f6d,CN=localhost,OU=techops,O=Example > Co,L=Boston,ST=MA,C=US
JS: subjectAltNames: []

I think that a problem is in this parts of code:

...  onFailure: function (task, error) {
                console.log('test1', error)
                reject(error);
            },....

Can you ask me any idea please, how to solution this error? How is the problem?

Many thax