Add LibreSSL support (and other openssl implementations)

Summary:
Common Name extraction by regex was failing on LibreSSL.
Now using RFC2253 to unamiguously format distinguished name subject strings.

Reviewed By: emilsjolander

Differential Revision: D8452825

fbshipit-source-id: a18d4162a7aed3b5bd8c2996ff3832877dac90db
This commit is contained in:
John Knox
2018-06-18 03:32:10 -07:00
committed by Facebook Github Bot
parent 0984103696
commit 8b2a2b12a3

View File

@@ -34,6 +34,12 @@ const appNotDebuggableRegex = /debuggable/;
const allowedAppNameRegex = /^[a-zA-Z0-9.\-]+$/; const allowedAppNameRegex = /^[a-zA-Z0-9.\-]+$/;
const allowedAppDirectoryRegex = /^\/[ a-zA-Z0-9.\-\/]+$/; const allowedAppDirectoryRegex = /^\/[ a-zA-Z0-9.\-\/]+$/;
const logTag = 'CertificateProvider'; const logTag = 'CertificateProvider';
/*
* RFC2253 specifies the unamiguous x509 subject format.
* However, even when specifying this, different openssl implementations
* wrap it differently, e.g "subject=X" vs "subject= X".
*/
const x509SubjectCNRegex = /[=,]\s*CN=([^,]*)(,.*)?$/;
export type SecureServerConfig = {| export type SecureServerConfig = {|
key: Buffer, key: Buffer,
@@ -286,20 +292,23 @@ export default class CertificateProvider {
extractAppNameFromCSR(csr: string): Promise<string> { extractAppNameFromCSR(csr: string): Promise<string> {
const csrFile = this.writeToTempFile(csr); const csrFile = this.writeToTempFile(csr);
return openssl('req', {in: csrFile, noout: true, subject: true}) return openssl('req', {
in: csrFile,
noout: true,
subject: true,
nameopt: true,
RFC2253: false,
})
.then(subject => { .then(subject => {
fs.unlink(csrFile); fs.unlink(csrFile);
return subject; return subject;
}) })
.then(subject => { .then(subject => {
return subject const matches = subject.trim().match(x509SubjectCNRegex);
.split('/') if (!matches || matches.length < 2) {
.filter(part => { throw new Error(`Cannot extract CN from ${subject}`);
return part.startsWith('CN='); }
}) return matches[1];
.map(part => {
return part.split('=')[1].trim();
})[0];
}) })
.then(appName => { .then(appName => {
if (!appName.match(allowedAppNameRegex)) { if (!appName.match(allowedAppNameRegex)) {