We've recently bounced up against a bug seemingly caused by a change made to the way Google is handling SSL trust in Google Apps Script on the Google Apps for Gov service. We have a few Apps Script systems - two in particular are a server monitoring system and a webservice-based calendar synchronization tool - which communicate with servers at our end over an SSL connection. This has worked fine for months, until ~9:15 PM on 20 Sept 2012, when almost all of these (and similar) connections began to fail due to an inability to trust the DOD-signed certificates which are mandatory for us on our end of things.
Stranger still is that this is somewhat inconsistent -- that is, I can successfully ask Google to connect to https://usuportal.usuhs.mil and it loads just fine. However, if I try any of:
https://www.us.army.mil
https://www.nps.edu
https://www.disa.mil
https://learning.usuhs.edu
... they all fail. I suspect that this is to do with the root cert which some servers tie themselves back to, suffice that all tying back to the "DOD Root CA-2" certificate as a terminator are failing - a real problem for us.
For our server monitoring we've been able to temporarily work around this by disabling SSL verification in Apps Script, but that option isn't available for accessing webservices [EDIT: we are using SoapService to handle WS requests and returns], leaving us unable to continue to use those tools for as long as this problem is in place. Given the precision with which we can identify when the relevant change happened, though, I should hope Google can at least (relatively) quickly pinpoint what happened.
If it's helpful, below is a quick Google Apps Script function which will log out success / failure based on whether it's able to trust the SSL certificate at the endpoint.
function checkSSL()
{
// The server to go look at to see if we can trust it.
// Again, usuportal.usuhs.mil has been observed to work; all others tested have failed
//
var serverToTest = "https://www.disa.mil";
// options defines the options which will be used by the UrlFetchApp to define its behavior.
// In this case, we may be interested in disabling SSL validation.
//
var options =
{
"validateHttpsCertificates" : false
};
// First, try without disabling validation
//
try {
response = UrlFetchApp.fetch(serverToTest);
Logger.log("I was able to reach " + serverToTest +" without disabling certificate validation.");
}
catch (e)
{
// Logger.log(e.toString());
Logger.log("I was not able to reach " + serverToTest +" without disabling certificate validation.");
}
// Now let's try it with validation disabled
//
try {
response = UrlFetchApp.fetch(serverToTest, options);
Logger.log("I was able to reach " + serverToTest +" with certificate validation disabled.");
}
catch (e)
{
// Logger.log(e.toString());
Logger.log("I was not able to reach " + serverToTest +" with certificate validation disabled. Maybe it's really just down?");
}
}