mirror of https://github.com/mongodb/mongo
SERVER-14861: Ensure that SSL hostname matching strictly follows RFC 2818
This commit is contained in:
parent
a4c1edab3d
commit
8954a165aa
|
|
@ -954,27 +954,24 @@ namespace mongo {
|
||||||
if (remoteHost.empty()) {
|
if (remoteHost.empty()) {
|
||||||
return peerSubjectName;
|
return peerSubjectName;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cnBegin = peerSubjectName.find("CN=") + 3;
|
|
||||||
int cnEnd = peerSubjectName.find(",", cnBegin);
|
|
||||||
std::string commonName = peerSubjectName.substr(cnBegin, cnEnd-cnBegin);
|
|
||||||
|
|
||||||
if (_hostNameMatch(remoteHost.c_str(), commonName.c_str())) {
|
|
||||||
return peerSubjectName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If Common Name (CN) didn't match, check Subject Alternate Name (SAN)
|
// Try to match using the Subject Alternate Name, if it exists.
|
||||||
|
// RFC-2818 requires the Subject Alternate Name to be used if present.
|
||||||
|
// Otherwise, the most specific Common Name field in the subject field
|
||||||
|
// must be used.
|
||||||
|
|
||||||
|
bool sanMatch = false;
|
||||||
|
bool cnMatch = false;
|
||||||
|
|
||||||
STACK_OF(GENERAL_NAME)* sanNames = static_cast<STACK_OF(GENERAL_NAME)*>
|
STACK_OF(GENERAL_NAME)* sanNames = static_cast<STACK_OF(GENERAL_NAME)*>
|
||||||
(X509_get_ext_d2i(peerCert, NID_subject_alt_name, NULL, NULL));
|
(X509_get_ext_d2i(peerCert, NID_subject_alt_name, NULL, NULL));
|
||||||
|
|
||||||
bool sanMatch = false;
|
|
||||||
if (sanNames != NULL) {
|
if (sanNames != NULL) {
|
||||||
int sanNamesList = sk_GENERAL_NAME_num(sanNames);
|
int sanNamesList = sk_GENERAL_NAME_num(sanNames);
|
||||||
|
|
||||||
for (int i = 0; i < sanNamesList; i++) {
|
for (int i = 0; i < sanNamesList; i++) {
|
||||||
const GENERAL_NAME* currentName = sk_GENERAL_NAME_value(sanNames, i);
|
const GENERAL_NAME* currentName = sk_GENERAL_NAME_value(sanNames, i);
|
||||||
if (currentName && currentName->type == GEN_DNS) {
|
if (currentName && currentName->type == GEN_DNS) {
|
||||||
char *dnsName =
|
char *dnsName =
|
||||||
reinterpret_cast<char *>(ASN1_STRING_data(currentName->d.dNSName));
|
reinterpret_cast<char *>(ASN1_STRING_data(currentName->d.dNSName));
|
||||||
if (_hostNameMatch(remoteHost.c_str(), dnsName)) {
|
if (_hostNameMatch(remoteHost.c_str(), dnsName)) {
|
||||||
sanMatch = true;
|
sanMatch = true;
|
||||||
|
|
@ -982,12 +979,22 @@ namespace mongo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sk_GENERAL_NAME_pop_free(sanNames, GENERAL_NAME_free);
|
||||||
}
|
}
|
||||||
sk_GENERAL_NAME_pop_free(sanNames, GENERAL_NAME_free);
|
else {
|
||||||
|
// If Subject Alternate Name (SAN) didn't exist, check Common Name (CN).
|
||||||
|
int cnBegin = peerSubjectName.find("CN=") + 3;
|
||||||
|
int cnEnd = peerSubjectName.find(",", cnBegin);
|
||||||
|
std::string commonName = peerSubjectName.substr(cnBegin, cnEnd-cnBegin);
|
||||||
|
|
||||||
if (!sanMatch) {
|
if (_hostNameMatch(remoteHost.c_str(), commonName.c_str())) {
|
||||||
|
cnMatch = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sanMatch && !cnMatch) {
|
||||||
if (_allowInvalidCertificates || _allowInvalidHostnames) {
|
if (_allowInvalidCertificates || _allowInvalidHostnames) {
|
||||||
warning() << "The server certificate does not match the host name " <<
|
warning() << "The server certificate does not match the host name " <<
|
||||||
remoteHost;
|
remoteHost;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue