{
char sha1_text[41];
const char *fingerprint;
+ unsigned min_match_len;
+ unsigned real_min_match_len = 4;
+ unsigned old_len, fingerprint_len;
if (strchr(old_hash, ':')) {
if (strncmp(old_hash, "sha1:", 5) == 0) {
fingerprint = vpninfo->peer_cert_sha1;
+ min_match_len = real_min_match_len + sizeof("sha1:")-1;
} else if (strncmp(old_hash, "sha256:", 7) == 0) {
fingerprint = vpninfo->peer_cert_sha256;
+ min_match_len = real_min_match_len + sizeof("sha256:")-1;
} else {
vpn_progress(vpninfo, PRG_ERR, _("Unknown certificate hash: %s.\n"), old_hash);
return -EIO;
sprintf(&sha1_text[i*2], "%02x", sha1_bin[i]);
fingerprint = sha1_text;
+ min_match_len = real_min_match_len;
}
- if (strcasecmp(old_hash, fingerprint))
- return 1;
+ old_len = strlen(old_hash);
+ fingerprint_len = strlen(fingerprint);
+
+ /* allow partial matches */
+ if (old_len < fingerprint_len) {
+ if (strncasecmp(old_hash, fingerprint, MAX(min_match_len, old_len))) {
+ if (old_len < min_match_len) {
+ vpn_progress(vpninfo, PRG_ERR, _("The size of the provided fingerprint is less than the minimum required (%u).\n"), real_min_match_len);
+ }
+ return 1;
+ }
+ } else {
+ if (strcasecmp(old_hash, fingerprint))
+ return 1;
+ }
return 0;
}
.IR IP
instead of using the normal resolver to look it up.
.TP
-.B \-\-servercert=SHA1
-Accept server's SSL certificate only if its fingerprint matches
-.IR SHA1 .
+.B \-\-servercert=HASH
+Accept server's SSL certificate only if the provided fingerprint matches.
+The allowed fingerprint types are
+.IR SHA1 ,
+and
+.IR SHA256 .
+They are distinguished by the 'sha1:' or 'sha256:' prefixes to the hex encoded
+hash. To ease certain testing use-cases, a partial match of the hash will also
+be accepted, if it is at least 4 characters.
.TP
.B \-\-useragent=STRING
Use