1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

Verify domain name in WiFiClientSecure::verify

This commit is contained in:
Ivan Grokhotkov 2016-02-26 18:38:04 +03:00
parent e206093b60
commit fcf9c0d7ce
2 changed files with 47 additions and 4 deletions

View File

@ -352,7 +352,33 @@ static bool parseHexNibble(char pb, uint8_t* res) {
return false; return false;
} }
bool WiFiClientSecure::verify(const char* fp, const char* url) { // Compare a name from certificate and domain name, return true if they match
static bool matchName(const String& name, const String& domainName)
{
int wildcardPos = name.indexOf('*');
if (wildcardPos == -1) {
// Not a wildcard, expect an exact match
return name == domainName;
}
int firstDotPos = name.indexOf('.');
if (wildcardPos > firstDotPos) {
// Wildcard is not part of leftmost component of domain name
// Do not attempt to match (rfc6125 6.4.3.1)
return false;
}
if (wildcardPos != 0 || firstDotPos != 1) {
// Matching of wildcards such as baz*.example.com and b*z.example.com
// is optional. Maybe implement this in the future?
return false;
}
int domainNameFirstDotPos = domainName.indexOf('.');
if (domainNameFirstDotPos < 0) {
return false;
}
return domainName.substring(domainNameFirstDotPos) == name.substring(firstDotPos);
}
bool WiFiClientSecure::verify(const char* fp, const char* domain_name) {
if (!_ssl) if (!_ssl)
return false; return false;
@ -380,9 +406,26 @@ bool WiFiClientSecure::verify(const char* fp, const char* url) {
return false; return false;
} }
//TODO: check URL against certificate DEBUGV("domain name: '%s'\r\n", (domain_name)?domain_name:"(null)");
String domain_name_str(domain_name);
domain_name_str.toLowerCase();
return true; const char* san = NULL;
int i = 0;
while((san = ssl_get_cert_subject_alt_dnsname(*_ssl, i)) != NULL) {
if (matchName(String(san), domain_name_str)) {
return true;
}
DEBUGV("SAN %d: '%s', no match\r\n", i, san);
++i;
}
const char* common_name = ssl_get_cert_dn(*_ssl, SSL_X509_CERT_COMMON_NAME);
if (common_name && matchName(String(common_name), domain_name_str)) {
return true;
}
DEBUGV("CN: '%s', no match\r\n", (common_name)?common_name:"(null)");
return false;
} }
void WiFiClientSecure::setCertificate(const uint8_t* cert_data, size_t size) { void WiFiClientSecure::setCertificate(const uint8_t* cert_data, size_t size) {

View File

@ -38,7 +38,7 @@ public:
int connect(IPAddress ip, uint16_t port) override; int connect(IPAddress ip, uint16_t port) override;
int connect(const char* name, uint16_t port) override; int connect(const char* name, uint16_t port) override;
bool verify(const char* fingerprint, const char* url); bool verify(const char* fingerprint, const char* domain_name);
uint8_t connected() override; uint8_t connected() override;
size_t write(const uint8_t *buf, size_t size) override; size_t write(const uint8_t *buf, size_t size) override;