mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-07-17 06:54:34 +00:00
Fix OpenSSL data parsing
OpenSSL data parsing could be confused when parsing certificates which have Country/Org and other parameters in the subject line. This is fixed by writing a more robust parser of the output lines, and using that to do parsing which now correctly handles this case.
This commit is contained in:
@ -726,6 +726,28 @@ const internalCertificate = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse the X509 subject line as returned by the OpenSSL command when
|
||||
* invoked with openssl x509 -in <certificate name> -subject -noout
|
||||
*
|
||||
* @param {String} line emitted from the openssl command
|
||||
* @param {String} prefix expected to be removed
|
||||
* @return {Object} object containing the parsed fields from the subject line
|
||||
*/
|
||||
parseX509Output: (line, prefix) => {
|
||||
// Remove the subject= part
|
||||
const subject_value = line.slice(prefix.length);
|
||||
|
||||
const subject = subject_value.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/)
|
||||
.map( (e) => { return e.trim().split(' = ', 2); })
|
||||
.reduce((obj, [key, value]) => {
|
||||
obj[key] = value.replace(/^"/, '').replace(/"$/, '');
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
return subject;
|
||||
},
|
||||
|
||||
/**
|
||||
* Uses the openssl command to both validate and get info out of the certificate.
|
||||
* It will save the file to disk first, then run commands on it, then delete the file.
|
||||
@ -739,28 +761,27 @@ const internalCertificate = {
|
||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -subject -noout')
|
||||
.then((result) => {
|
||||
// subject=CN = something.example.com
|
||||
const regex = /(?:subject=)?[^=]+=\s+(\S+)/gim;
|
||||
const match = regex.exec(result);
|
||||
// subject=C = NoCountry, O = NoOrg, OU = NoOrgUnit, CN = Some Value With Spaces
|
||||
const subjectParams = internalCertificate.parseX509Output(result, 'subject=');
|
||||
|
||||
if (typeof match[1] === 'undefined') {
|
||||
if (typeof subjectParams.CN === 'undefined') {
|
||||
throw new error.ValidationError('Could not determine subject from certificate: ' + result);
|
||||
}
|
||||
|
||||
certData['cn'] = match[1];
|
||||
certData['cn'] = subjectParams.CN;
|
||||
})
|
||||
.then(() => {
|
||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -issuer -noout');
|
||||
})
|
||||
.then((result) => {
|
||||
// issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
|
||||
const regex = /^(?:issuer=)?(.*)$/gim;
|
||||
const match = regex.exec(result);
|
||||
const issuerParams = internalCertificate.parseX509Output(result, 'issuer=');
|
||||
|
||||
if (typeof match[1] === 'undefined') {
|
||||
if (typeof issuerParams.CN === 'undefined') {
|
||||
throw new error.ValidationError('Could not determine issuer from certificate: ' + result);
|
||||
}
|
||||
|
||||
certData['issuer'] = match[1];
|
||||
certData['issuer'] = issuerParams.CN;
|
||||
})
|
||||
.then(() => {
|
||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -dates -noout');
|
||||
|
Reference in New Issue
Block a user