Back out "[flipper] Add 1h tolerance to ssl certs"

Summary:
Original commit changeset: bdbd61bce1bc

That change appears to be causing some issues for open source users: https://github.com/facebook/flipper/issues/498

To mitigate the issue I'm reverting it, the change turns out to be unnecessary anyway.

Reviewed By: passy

Differential Revision: D16486136

fbshipit-source-id: 70decca6e017a6a2903cc484641fb2e736dc5d7c
This commit is contained in:
John Knox
2019-07-25 03:59:55 -07:00
committed by Facebook Github Bot
parent a903c7ddc6
commit d0a61d6455
3 changed files with 60 additions and 121 deletions

View File

@@ -84,7 +84,6 @@
"codemirror": "^5.25.0", "codemirror": "^5.25.0",
"cross-env": "^5.2.0", "cross-env": "^5.2.0",
"dashify": "^2.0.0", "dashify": "^2.0.0",
"dateformat": "^3.0.3",
"deep-equal": "^1.0.1", "deep-equal": "^1.0.1",
"detect-port": "^1.1.1", "detect-port": "^1.1.1",
"electron-devtools-installer": "^2.2.0", "electron-devtools-installer": "^2.2.0",

View File

@@ -21,9 +21,6 @@ import iosUtil from '../fb-stubs/iOSContainerUtility';
import {reportPlatformFailures} from './metrics'; import {reportPlatformFailures} from './metrics';
import {getAdbClient} from './adbClient'; import {getAdbClient} from './adbClient';
import * as androidUtil from './androidContainerUtility'; import * as androidUtil from './androidContainerUtility';
import dateFormat from 'dateformat';
const writeFile = promisify(fs.writeFile);
const exists = promisify(fs.exists);
// Desktop file paths // Desktop file paths
const os = require('os'); const os = require('os');
@@ -31,20 +28,16 @@ const caKey = getFilePath('ca.key');
const caCert = getFilePath('ca.crt'); const caCert = getFilePath('ca.crt');
const serverKey = getFilePath('server.key'); const serverKey = getFilePath('server.key');
const serverCsr = getFilePath('server.csr'); const serverCsr = getFilePath('server.csr');
const serverSrl = getFilePath('server.srl');
const serverCert = getFilePath('server.crt'); const serverCert = getFilePath('server.crt');
const configFile = getFilePath('openssl.cfg');
const certs = getFilePath('certs');
const newCerts = getFilePath('newcerts');
const database = getFilePath('index.txt');
const caRequiredFiles = [caKey, caCert, newCerts, database, configFile];
// Device file paths // Device file paths
const csrFileName = 'app.csr'; const csrFileName = 'app.csr';
const deviceCAcertFile = 'sonarCA.crt'; const deviceCAcertFile = 'sonarCA.crt';
const deviceClientCertFile = 'device.crt'; const deviceClientCertFile = 'device.crt';
const caSubject = '/C=US/ST=CA/L=Menlo Park/O=Flipper/CN=SonarCA'; const caSubject = '/C=US/ST=CA/L=Menlo Park/O=Sonar/CN=SonarCA';
const serverSubject = '/C=US/ST=CA/L=Menlo Park/O=Flipper/CN=localhost'; const serverSubject = '/C=US/ST=CA/L=Menlo Park/O=Sonar/CN=localhost';
const minCertExpiryWindowSeconds = 24 * 60 * 60; const minCertExpiryWindowSeconds = 24 * 60 * 60;
const allowedAppNameRegex = /^[a-zA-Z0-9._\-]+$/; const allowedAppNameRegex = /^[a-zA-Z0-9._\-]+$/;
const logTag = 'CertificateProvider'; const logTag = 'CertificateProvider';
@@ -55,42 +48,6 @@ const logTag = 'CertificateProvider';
*/ */
const x509SubjectCNRegex = /[=,]\s*CN=([^,]*)(,.*)?$/; const x509SubjectCNRegex = /[=,]\s*CN=([^,]*)(,.*)?$/;
const opensslConfig = `####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = ${getFilePath('')} # Where everything is kept
certs = ${certs} # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = ${database} # database index file.
unique_subject = no # allow creation of several certs with same subject.
new_certs_dir = ${newCerts} # default place for new certs.
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
crl = $dir/crl.pem # The current CRL
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = default # use public key default MD
preserve = no # keep passed DN ordering
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional`;
export type SecureServerConfig = {| export type SecureServerConfig = {|
key: Buffer, key: Buffer,
cert: Buffer, cert: Buffer,
@@ -99,12 +56,6 @@ export type SecureServerConfig = {|
rejectUnauthorized: boolean, rejectUnauthorized: boolean,
|}; |};
function getCertStartDate(): string {
const date = new Date();
date.setHours(date.getHours() - 1);
return dateFormat(date, 'yyyymmddHHMMss') + 'Z';
}
/* /*
* This class is responsible for generating and deploying server and client * This class is responsible for generating and deploying server and client
* certificates to allow for secure communication between Flipper and apps. * certificates to allow for secure communication between Flipper and apps.
@@ -126,10 +77,8 @@ export default class CertificateProvider {
this.logger = logger; this.logger = logger;
this.adb = getAdbClient(); this.adb = getAdbClient();
this.certificateSetup = reportPlatformFailures( this.certificateSetup = reportPlatformFailures(
this.ensureCertificateAuthorityExists().then(_ => this.ensureServerCertExists(),
this.ensureServerCertExists(), 'ensureServerCertExists',
),
'certificateSetup',
); );
this.server = server; this.server = server;
} }
@@ -213,14 +162,13 @@ export default class CertificateProvider {
console.debug('Creating new client cert', logTag); console.debug('Creating new client cert', logTag);
return this.writeToTempFile(csr).then(path => { return this.writeToTempFile(csr).then(path => {
return openssl('ca', { return openssl('x509', {
cert: caCert, req: true,
in: path, in: path,
keyfile: caKey, CA: caCert,
config: configFile, CAkey: caKey,
batch: true, CAcreateserial: true,
startdate: getCertStartDate(), CAserial: serverSrl,
create_serial: true,
}); });
}); });
} }
@@ -252,33 +200,35 @@ export default class CertificateProvider {
); );
} }
if (os === 'iOS' || os === 'windows') { if (os === 'iOS' || os === 'windows') {
return writeFile(destination + filename, contents).catch(err => { return promisify(fs.writeFile)(destination + filename, contents).catch(
if (os === 'iOS') { err => {
// Writing directly to FS failed. It's probably a physical device. if (os === 'iOS') {
const relativePathInsideApp = this.getRelativePathInAppContainer( // Writing directly to FS failed. It's probably a physical device.
destination, const relativePathInsideApp = this.getRelativePathInAppContainer(
destination,
);
return appNamePromise
.then(appName =>
this.getTargetiOSDeviceId(appName, destination, csr),
)
.then(udid => {
return appNamePromise.then(appName =>
this.pushFileToiOSDevice(
udid,
appName,
relativePathInsideApp,
filename,
contents,
),
);
});
}
throw new Error(
`Invalid appDirectory recieved from ${os} device: ${destination}: ` +
err.toString(),
); );
return appNamePromise },
.then(appName => );
this.getTargetiOSDeviceId(appName, destination, csr),
)
.then(udid => {
return appNamePromise.then(appName =>
this.pushFileToiOSDevice(
udid,
appName,
relativePathInsideApp,
filename,
contents,
),
);
});
}
throw new Error(
`Invalid appDirectory recieved from ${os} device: ${destination}: ` +
err.toString(),
);
});
} }
return Promise.reject(new Error(`Unsupported device os: ${os}`)); return Promise.reject(new Error(`Unsupported device os: ${os}`));
} }
@@ -292,7 +242,7 @@ export default class CertificateProvider {
): Promise<void> { ): Promise<void> {
return tmpDir({unsafeCleanup: true}).then(dir => { return tmpDir({unsafeCleanup: true}).then(dir => {
const filePath = path.resolve(dir, filename); const filePath = path.resolve(dir, filename);
writeFile(filePath, contents).then(() => promisify(fs.writeFile)(filePath, contents).then(() =>
iosUtil.push(udid, filePath, bundleId, destination), iosUtil.push(udid, filePath, bundleId, destination),
); );
}); });
@@ -488,15 +438,12 @@ export default class CertificateProvider {
} }
ensureCertificateAuthorityExists(): Promise<void> { ensureCertificateAuthorityExists(): Promise<void> {
return Promise.all(caRequiredFiles.map(exists)) if (!fs.existsSync(caKey)) {
.then(results => results.every(Boolean)) return this.generateCertificateAuthority();
.then(hasRequiredFiles => }
hasRequiredFiles return this.checkCertIsValid(caCert).catch(e =>
? Promise.resolve() this.generateCertificateAuthority(),
: this.generateCertificateAuthority(), );
)
.then(_ => this.checkCertIsValid(caCert))
.catch(e => this.generateCertificateAuthority());
} }
checkCertIsValid(filename: string): Promise<void> { checkCertIsValid(filename: string): Promise<void> {
@@ -558,12 +505,11 @@ export default class CertificateProvider {
} }
generateCertificateAuthority(): Promise<void> { generateCertificateAuthority(): Promise<void> {
if (!fs.existsSync(getFilePath(''))) {
fs.mkdirSync(getFilePath(''));
}
console.log('Generating new CA', logTag); console.log('Generating new CA', logTag);
return promisify(fs.mkdir)(getFilePath(''), {recursive: true}) return openssl('genrsa', {out: caKey, '2048': false})
.then(_ => writeFile(configFile, opensslConfig))
.then(_ => writeFile(database, ''))
.then(_ => promisify(fs.mkdir)(newCerts, {recursive: true}))
.then(_ => openssl('genrsa', {out: caKey, '2048': false}))
.then(_ => .then(_ =>
openssl('req', { openssl('req', {
new: true, new: true,
@@ -606,24 +552,23 @@ export default class CertificateProvider {
subj: serverSubject, subj: serverSubject,
}), }),
) )
.then(_ => { .then(_ =>
return openssl('ca', { openssl('x509', {
cert: caCert, req: true,
in: serverCsr, in: serverCsr,
keyfile: caKey, CA: caCert,
CAkey: caKey,
CAcreateserial: true,
CAserial: serverSrl,
out: serverCert, out: serverCert,
config: configFile, }),
batch: true, )
startdate: getCertStartDate(),
create_serial: true,
});
})
.then(_ => undefined); .then(_ => undefined);
} }
writeToTempFile(content: string): Promise<string> { writeToTempFile(content: string): Promise<string> {
return tmpFile().then((path, fd, cleanupCallback) => return tmpFile().then((path, fd, cleanupCallback) =>
writeFile(path, content).then(_ => path), promisify(fs.writeFile)(path, content).then(_ => path),
); );
} }
} }

View File

@@ -2480,11 +2480,6 @@ data-urls@^1.0.0:
whatwg-mimetype "^2.1.0" whatwg-mimetype "^2.1.0"
whatwg-url "^7.0.0" whatwg-url "^7.0.0"
dateformat@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
debug@2.6.9, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9, debug@~2.6.3: debug@2.6.9, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9, debug@~2.6.3:
version "2.6.9" version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"