{ "id": "146811", "key": "TIMOB-18861", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "16593", "description": "Release 4.0.0", "name": "Release 4.0.0", "archived": false, "released": true, "releaseDate": "2015-05-21" }, { "id": "16723", "description": "Windows Platform Support, ListView updates, Vector overlays in maps", "name": "Release 4.1.0", "archived": false, "released": true, "releaseDate": "2015-07-08" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2015-04-29T22:49:29.000+0000", "created": "2015-04-10T16:43:30.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [], "versions": [], "issuelinks": [ { "id": "47434", "type": { "id": "10122", "name": "Gantt: start-finish", "inward": "is triggered by", "outward": "is triggering" }, "inwardIssue": { "id": "138845", "key": "TIMOB-17948", "fields": { "summary": "Android: Support SSL SNI on Apache HTTP Client", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false } } } }, { "id": "47208", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "146546", "key": "TISTUD-7375", "fields": { "summary": "Dashboard won't load", "status": { "description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.", "name": "Resolved", "id": "5", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-03-16T22:48:37.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "The Android mobile app for Appcelerator University cannot connect to the API due to an SSL certificate validation failure. The error message suggests the server certificate is for *.cloudapp-enterprise.appcelerator.com:\r\n\r\n{code}\r\nHTTP Error (javax.net.ssl.SSLException): hostname in certificate didn't match: != <*.cloudapp-enterprise.appcelerator.com> OR <*.cloudapp-enterprise.appcelerator.com> OR \r\n{code}\r\n\r\nIf I do a cURL, the SSL certificate is for *.appcelerator.com:\r\n\r\n{code}\r\ncurl -v -s -H \"Authorization: Basic VGswNHhoMjdNeGlCTEdWMHU3MlVkUlBDZzNYNHd0WmI6\" https://university.appcelerator.com/api/app/config 1> /dev/null \r\n* Hostname was NOT found in DNS cache\r\n* Trying 54.244.121.15...\r\n* Connected to university.appcelerator.com (54.244.121.15) port 443 (#0)\r\n* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384\r\n* Server certificate: *.appcelerator.com\r\n* Server certificate: Go Daddy Secure Certificate Authority - G2\r\n* Server certificate: Go Daddy Root Certificate Authority - G2\r\n> GET /api/app/config HTTP/1.1\r\n> User-Agent: curl/7.37.1\r\n> Host: university.appcelerator.com\r\n> Accept: */*\r\n> Authorization: Basic VGswNHhoMjdNeGlCTEdWMHU3MlVkUlBDZzNYNHd0WmI6\r\n> \r\n< HTTP/1.1 200 OK\r\n< X-Powered-By: Appcelerator Node.ACS\r\n< X-Response-time: 8ms\r\n* Server Appcelerator Arrow/0.3.167 is not blacklisted\r\n< server: Appcelerator Arrow/0.3.167\r\n< request-id: fdea4777-3ec4-4552-a782-a66992bb724c\r\n< content-type: application/json\r\n< content-length: 129\r\n< date: Fri, 10 Apr 2015 16:42:11 GMT\r\n< connection: close\r\n< \r\n{ [data not shown]\r\n* Closing connection 0\r\n{code}\r\n\r\nHere's the ACS details for the published Appcelerator University Arrow app:\r\n\r\n{code}\r\nApp name: AppU\r\n -- Created by: rblalock@appcelerator.com\r\n -- URL: https://0df0b36af43e31f224953e4d270bcb256b86677c.cloudapp-enterprise.appcelerator.com\r\n -- DOMAIN: university.appcelerator.com\r\n -- Created at: Sat Mar 21 2015 03:55:30 GMT+0000 (GMT)\r\n -- Node Version: 0.10.22\r\n -- Server Size: Large\r\n -- Maximum allowed number of servers: 5\r\n -- Desired minimum number of servers: 3\r\n -- Current number of deployed servers: 3\r\n -- Auto scale-up enabled: true\r\n -- Maximum queued requests per server: 50\r\n -- Auto scale-down enabled: true\r\n -- Active version: 1.0.11\r\n -- Published at: Thu Apr 09 2015 02:41:16 GMT+0100 (BST)\r\n -- Status: Active\r\n -- Servers: \r\n No. 1\tID: 551c756413a34aafa5f90281\tStatus: Deployed\r\n No. 2\tID: 551c757813a34aafa5f90285\tStatus: Deployed\r\n No. 3\tID: 551c75c713a34aafa5f90295\tStatus: Deployed\r\n{code}", "attachment": [], "flagged": false, "summary": "SSL certificate validation fails on university.appcelerator.com on Android", "creator": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "subtasks": [], "reporter": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "environment": null, "closedSprints": [ { "id": 398, "state": "closed", "name": "2015 Sprint 09 SDK", "startDate": "2015-04-25T00:00:00.000Z", "endDate": "2015-05-09T00:00:00.000Z", "completeDate": "2015-05-11T14:11:17.028Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "349199", "author": { "name": "mgoff", "key": "mgoff", "displayName": "Michael Goff", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~cbowley] is this running on an Android simulator or phone? Which Android version and phone model?\r\n\r\nWe occasionally see issues with older Android versions when handling SSL certificates.", "updateAuthor": { "name": "mgoff", "key": "mgoff", "displayName": "Michael Goff", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-10T18:40:08.000+0000", "updated": "2015-04-10T18:40:08.000+0000" }, { "id": "349200", "author": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "body": "[~mgoff] this is on device. I have the same error on:\r\n\r\nNexus 5, Android 5.0\r\nGalaxy Tab 10.1 2. Android 4.2.2\r\n\r\nBuilt using Ti 3.5.1.\r\n\r\nDo we even serve a *.cloudapp-enterprise.appcelerator.com certificate?", "updateAuthor": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "created": "2015-04-10T18:45:36.000+0000", "updated": "2015-04-10T18:45:36.000+0000" }, { "id": "349230", "author": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "body": "I get the same error if I try to access the Studio dashboard Arrow app API from Android:\r\n\r\nEquivalent cURL command:\r\n\r\n{code}\r\ncurl -v -s -H \"Authorization: Basic TldmTmg1N1d3b3d5blNvRW9kVDM0cVM1c1VMYmU0Mmg6\" https://appc-studio.appcelerator.com/api/appu/library\r\n{code}\r\n\r\nError when requested from Android:\r\n\r\n{code}\r\nHTTP Error (javax.net.ssl.SSLException): hostname in certificate didn't match: \r\n != <*.cloudapp-enterprise.appcelerator.com> \r\nOR <*.cloudapp-enterprise.appcelerator.com> \r\nOR \r\n{code}", "updateAuthor": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "created": "2015-04-11T12:02:39.000+0000", "updated": "2015-04-11T12:12:22.000+0000" }, { "id": "349231", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "I've had these kind of errors on Android apps before. I then learned that Android is very picky about the right order of the SSL certificate chain. You can find a lot about that on Google: https://www.google.nl/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=order+of+certificates+chain+android", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-04-11T12:15:43.000+0000", "updated": "2015-04-11T12:15:43.000+0000" }, { "id": "349232", "author": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "body": "Thanks [~fokkezb]. Here's the results I get for university.appcelerator.com: https://www.ssllabs.com/ssltest/analyze.html?d=university.appcelerator.com&s=54.244.121.14&hideResults=on. No reference to *.cloudapp-enterprise.appcelerator.com.", "updateAuthor": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "created": "2015-04-11T12:28:02.000+0000", "updated": "2015-04-11T12:28:02.000+0000" }, { "id": "349233", "author": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "body": "If I make the request using the original URL, I get the *.cloudapp-enterprise.appcelerator.com certificate. Which means Android is resolving the CNAME URL?\r\n\r\n{code}\r\ncurl -v -s -H \"Authorization: Basic TldmTmg1N1d3b3d5blNvRW9kVDM0cVM1c1VMYmU0Mmg6\" https://c968c356eab0ac3c3a3bb8759ff6acc7eebc70a0.cloudapp-enterprise.appcelerator.com/api/appu/library\r\n* Hostname was NOT found in DNS cache\r\n* Trying 54.244.121.14...\r\n* Connected to c968c356eab0ac3c3a3bb8759ff6acc7eebc70a0.cloudapp-enterprise.appcelerator.com (54.244.121.14) port 443 (#0)\r\n* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384\r\n* Server certificate: *.cloudapp-enterprise.appcelerator.com\r\n* Server certificate: Go Daddy Secure Certificate Authority - G2\r\n* Server certificate: Go Daddy Root Certificate Authority - G2\r\n> GET /api/appu/library HTTP/1.1\r\n> User-Agent: curl/7.37.1\r\n> Host: c968c356eab0ac3c3a3bb8759ff6acc7eebc70a0.cloudapp-enterprise.appcelerator.com\r\n> Accept: */*\r\n> Authorization: Basic TldmTmg1N1d3b3d5blNvRW9kVDM0cVM1c1VMYmU0Mmg6\r\n> \r\n< HTTP/1.1 200 OK\r\n< X-Powered-By: Appcelerator Node.ACS\r\n< X-Response-time: 175ms\r\n* Server Appcelerator Arrow/0.3.167 is not blacklisted\r\n< server: Appcelerator Arrow/0.3.167\r\n< request-id: d272786f-31e7-4685-9fcd-84c53d6bd430\r\n< content-type: application/json\r\n< content-length: 33610\r\n< date: Sat, 11 Apr 2015 12:30:54 GMT\r\n< connection: close\r\n{code}", "updateAuthor": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "created": "2015-04-11T12:32:07.000+0000", "updated": "2015-04-11T12:32:07.000+0000" }, { "id": "350662", "author": { "name": "mgoff", "key": "mgoff", "displayName": "Michael Goff", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~cbowley] [~ingo] One potential cause of the mismatch only from Android (when browsers and iOS are working fine) could be how it handles virtual hosting. From https://developer.android.com/training/articles/security-ssl.html:\r\n\r\n{quote}\r\nFortunately, HttpsURLConnection supports SNI since Android 2.3. Unfortunately, Apache HTTP Client does not, which is one of the many reasons we discourage its use. One workaround if you need to support Android 2.2 (and older) or Apache HTTP Client is to set up an alternative virtual host on a unique port so that it's unambiguous which server certificate to return.\r\n{quote}\r\n\r\nWhich one do we use? Our HAProxy load balancer in Node.ACS utilizes SNI to choose the right SSL certificate to return.", "updateAuthor": { "name": "mgoff", "key": "mgoff", "displayName": "Michael Goff", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-24T15:47:07.000+0000", "updated": "2015-04-24T15:51:40.000+0000" }, { "id": "350665", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "We specifically had to make a change for this WRT to building apps and the security server. Also see TIMOB-17948. It sounds like we should bump up the priority there.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-24T16:01:43.000+0000", "updated": "2015-04-24T16:01:43.000+0000" }, { "id": "350667", "author": { "name": "mgoff", "key": "mgoff", "displayName": "Michael Goff", "active": true, "timeZone": "America/Los_Angeles" }, "body": "SNI support is absolutely required for Ti apps to access Arrow Cloud (Node.ACS) apps.", "updateAuthor": { "name": "mgoff", "key": "mgoff", "displayName": "Michael Goff", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-24T16:15:50.000+0000", "updated": "2015-04-24T16:15:50.000+0000" }, { "id": "350668", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Well, ack. [~hpham] and [~emerriman], let's discuss today.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-24T16:18:01.000+0000", "updated": "2015-04-24T16:18:01.000+0000" }, { "id": "350697", "author": { "name": "mgoff", "key": "mgoff", "displayName": "Michael Goff", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~hpham] this seems to be an issue for Arrow apps which add their own SSL certificates and CNAME. Try the same Android code with university.appcelerator.com as the URL. Or I could add a SSL cert and CNAME to the app you just published to try and recreate the issue.", "updateAuthor": { "name": "mgoff", "key": "mgoff", "displayName": "Michael Goff", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-24T20:25:45.000+0000", "updated": "2015-04-24T20:26:25.000+0000" }, { "id": "350701", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Mike, I just tried this:\r\n{code}\r\nvar xhr = Ti.Network.createHTTPClient({\r\n onload: function onLoad() {\r\n alert(\"Loaded: \" + this.status + \": \" + this.responseText);\r\n },\r\n onerror: function onError() {\r\n alert(\"Errored: \" + this.status + \": \" + this.responseText);\r\n }\r\n});\r\n\r\nxhr.open(\"GET\",\"https://university.appcelerator.com\");\r\n//var authstr = 'Basic ' + Ti.Utils.base64encode('VGswNHhoMjdNeGlCTEdWMHU3MlVkUlBDZzNYNHd0WmI6:');\r\n//xhr.setRequestHeader(\"Authorization\", authstr);\r\nxhr.send();\r\n{code}\r\n\r\nI get code 200. Works fine for me.", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-24T20:38:21.000+0000", "updated": "2015-04-24T20:38:21.000+0000" }, { "id": "350713", "author": { "name": "mgoff", "key": "mgoff", "displayName": "Michael Goff", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~ingo], I configured a CNAME for [~hpham]'s Arrow app which uses the same SSL cert as university.appcelerator.com, and he was not able to produce the problem with 4.0.0.RC. How do you wish to proceed? Run the same test with Ti 3.5.1 that Chris used? Or be content that it works on 4.0?\r\n\r\n{code}\r\nvar xhr = Ti.Network.createHTTPClient({\r\n onload: function onLoad() {\r\n alert(\"Loaded: \" + this.status + \": \" + this.responseText);\r\n },\r\n onerror: function onError() {\r\n alert(\"Errored: \" + this.status + \": \" + this.responseText);\r\n }\r\n});\r\n\r\nxhr.open(\"GET\",\"https://devops-4514.appcelerator.com/\");\r\n//var authstr = 'Basic ' + Ti.Utils.base64encode('VGswNHhoMjdNeGlCTEdWMHU3MlVkUlBDZzNYNHd0WmI6:');\r\n//xhr.setRequestHeader(\"Authorization\", authstr);\r\nxhr.send();\r\n{code}\r\n\r\n{code}\r\n$ acs list\r\nACS: Appcelerator Cloud Services Command-Line Interface, version 1.0.23\r\nCopyright (c) 2012-2015, Appcelerator, Inc. All Rights Reserved.\r\n\r\nAdmin Hostname: https://admin.cloudapp-enterprise.appcelerator.com\r\n\r\nOrganization: ChaosMonkey (100006264)\r\n============\r\nPoints:\r\n -- Quota: 45\r\n -- Used: 1\r\n\r\nApp name: TestArrow\r\n -- Created by: hpham@appcelerator.com\r\n -- URL: https://586f26424b0714864876ac62d861a5fe70b83624.cloudapp-enterprise.appcelerator.com\r\n -- DOMAIN: devops-4514.appcelerator.com\r\n -- Created at: Fri Apr 24 2015 11:42:45 GMT-0700 (PDT)\r\n -- Node Version: 0.10.22\r\n -- Server Size: Dev\r\n -- Maximum allowed number of servers: 1\r\n -- Desired minimum number of servers: 1\r\n -- Current number of deployed servers: 1\r\n -- Active version: 1.0.0\r\n -- Published at: Fri Apr 24 2015 13:03:52 GMT-0700 (PDT)\r\n -- Status: Active\r\n -- Servers:\r\n No. 1\tID: 5539092013a34aafa5fe484d\tStatus: Deployed\r\n\r\n$ dig +short devops-4514.appcelerator.com\r\n586f26424b0714864876ac62d861a5fe70b83624.cloudapp-enterprise.appcelerator.com.\r\nec2-54-244-121-15.us-west-2.compute.amazonaws.com.\r\n54.244.121.15\r\n{code}", "updateAuthor": { "name": "mgoff", "key": "mgoff", "displayName": "Michael Goff", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-24T22:21:41.000+0000", "updated": "2015-04-24T22:23:26.000+0000" }, { "id": "350714", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~cbowley] can you please take a look at [~hpham]'s code above and see what the difference might be?", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-24T22:23:17.000+0000", "updated": "2015-04-24T22:23:17.000+0000" }, { "id": "350843", "author": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "body": "[~hpham] [~mgoff] [~imuschenetz@appcelerator.com] by default the SSL certificate is not validated in development. You need to add\r\n\r\n{code}\r\nxhr.validatesSecureCertificate = true;\r\n{code}\r\n\r\nbefore the xhr.open() call. This is true by default in production.", "updateAuthor": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "created": "2015-04-27T07:51:38.000+0000", "updated": "2015-04-27T07:51:38.000+0000" }, { "id": "350898", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Testing code\r\n{code}\r\nvar xhr = Ti.Network.createHTTPClient({\r\n onload: function onLoad() {\r\n alert(\"Loaded: \" + this.status + \": \" + this.responseText);\r\n },\r\n onerror: function onError() {\r\n alert(\"Errored: \" + this.status + \": \" + this.responseText);\r\n }\r\n});\r\nxhr.validatesSecureCertificate = true;\r\nxhr.open(\"GET\",\"https://devops-4514.appcelerator.com/\");\r\nxhr.send();\r\n{code}\r\n\r\n1. Run and make sure you get code 200", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-27T18:06:00.000+0000", "updated": "2015-04-29T19:34:40.000+0000" }, { "id": "350937", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I was able to reproduce this on Eclipse, Appcelerator Studio works fine for some reason. I added support for SNI here: \r\nhttps://github.com/appcelerator/titanium_mobile/pull/6807", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-04-28T00:28:42.000+0000", "updated": "2015-04-28T00:28:42.000+0000" }, { "id": "413423", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as fixed.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-16T22:48:37.000+0000", "updated": "2017-03-16T22:48:37.000+0000" } ], "maxResults": 19, "total": 19, "startAt": 0 } } }