MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / tlsCheckCertificateAgainstAllowlist

Function tlsCheckCertificateAgainstAllowlist

src/tls.cpp:571–641  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

569};
570
571bool tlsCheckCertificateAgainstAllowlist(tls_connection* conn, std::set<sdsstring> allowlist, const char** commonName){
572 if (allowlist.empty()){
573 // An empty list implies acceptance of all
574 return true;
575 }
576
577 X509 * cert = SSL_get_peer_certificate(conn->ssl);
578 TCleanup certClen([cert]{X509_free(cert);});
579
580 /* Check the common name (CN) of the certificate first */
581 X509_NAME_ENTRY * ne = X509_NAME_get_entry(X509_get_subject_name(cert), X509_NAME_get_index_by_NID(X509_get_subject_name(cert), NID_commonName, -1));
582 *commonName = reinterpret_cast<const char*>(ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(ne)));
583
584 tlsSetCertificateFingerprint(conn, cert);
585
586 if (tlsCheckAgainstAllowlist(*commonName, allowlist)) {
587 return true;
588 }
589
590 /* If that fails, check through the subject alternative names (SANs) as well */
591 GENERAL_NAMES* subjectAltNames = (GENERAL_NAMES*)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
592 if (subjectAltNames != nullptr){
593 for (int i = 0; i < sk_GENERAL_NAME_num(subjectAltNames); i++)
594 {
595 GENERAL_NAME* generalName = sk_GENERAL_NAME_value(subjectAltNames, i);
596 /* Short circuit if one of the SANs match.
597 * We only support DNS, EMAIL, URI, and IP (specifically IPv4) */
598 switch (generalName->type)
599 {
600 case GEN_EMAIL:
601 if (tlsCheckAgainstAllowlist(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.rfc822Name)), allowlist)){
602 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
603 return true;
604 }
605 break;
606 case GEN_DNS:
607 if (tlsCheckAgainstAllowlist(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)), allowlist)){
608 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
609 return true;
610 }
611 break;
612 case GEN_URI:
613 if (tlsCheckAgainstAllowlist(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.uniformResourceIdentifier)), allowlist)){
614 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
615 return true;
616 }
617 break;
618 case GEN_IPADD:
619 {
620 int ipLen = ASN1_STRING_length(generalName->d.iPAddress);
621 if (ipLen == 4){ //IPv4 case
622 char addr[INET_ADDRSTRLEN];
623 inet_ntop(AF_INET, ASN1_STRING_get0_data(generalName->d.iPAddress), addr, INET_ADDRSTRLEN);
624 if (tlsCheckAgainstAllowlist(addr, allowlist)){
625 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
626 return true;
627 }
628 } else if (ipLen == 16) { // IPv6 case

Callers 2

Calls 3

tlsCheckAgainstAllowlistFunction · 0.85
emptyMethod · 0.45

Tested by

no test coverage detected