/* * Check if the SSL/TLS certificate exists in the certificates file. */ int check_cert(X509 *pcert, unsigned char *pmd, unsigned int *pmdlen) { int n, r; FILE *fd; char b; char *certf; X509 *cert; unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; r = 0; cert = NULL; n = snprintf(&b, 1, "%s/%s", env.home, PATHNAME_CERTS); if (env.pathmax != -1 && n > env.pathmax) fatal(ERROR_PATHNAME, "pathname limit %ld exceeded: %d\n", env.pathmax, n); certf = (char *)xmalloc((n + 1) * sizeof(char)); snprintf(certf, n + 1, "%s/%s", env.home, PATHNAME_CERTS); if (!exists_file(certf)) { xfree(certf); return 0; } fd = fopen(certf, "r"); xfree(certf); if (fd == NULL) return -1; while ((cert = PEM_read_X509(fd, &cert, NULL, NULL)) != NULL) { if (X509_subject_name_cmp(cert, pcert) != 0 || X509_issuer_name_cmp(cert, pcert) != 0) continue; if (!X509_digest(cert, EVP_md5(), md, &mdlen) || *pmdlen != mdlen) continue; if (memcmp(pmd, md, mdlen) != 0) { r = -1; break; } r = 1; break; } fclose(fd); X509_free(cert); return r; }
/* * Check if the SSL/TLS certificate exists in the certificates file. */ int check_cert(X509 *pcert, unsigned char *pmd, unsigned int *pmdlen) { int r; FILE *fd; char *certf; X509 *cert; unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; r = 0; cert = NULL; certf = get_filepath("certificates"); if (!exists_file(certf)) { xfree(certf); return 0; } fd = fopen(certf, "r"); xfree(certf); if (fd == NULL) return -1; while ((cert = PEM_read_X509(fd, &cert, NULL, NULL)) != NULL) { if (X509_subject_name_cmp(cert, pcert) != 0 || X509_issuer_name_cmp(cert, pcert) != 0) continue; if (!X509_digest(cert, EVP_md5(), md, &mdlen) || *pmdlen != mdlen) continue; if (memcmp(pmd, md, mdlen) != 0) { r = -1; break; } r = 1; break; } fclose(fd); X509_free(cert); return r; }
/** * compare_certificates - Compare two X509 certificated * @param cert Certificate * @param peercert Peer certificate * @param peermd Peer certificate message digest * @param peermdlen Length of peer certificate message digest * @retval true Certificates match * @retval false Certificates differ */ static bool compare_certificates(X509 *cert, X509 *peercert, unsigned char *peermd, unsigned int peermdlen) { unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; /* Avoid CPU-intensive digest calculation if the certificates are * not even remotely equal. */ if ((X509_subject_name_cmp(cert, peercert) != 0) || (X509_issuer_name_cmp(cert, peercert) != 0)) return false; if (!X509_digest(cert, EVP_sha256(), md, &mdlen) || (peermdlen != mdlen)) return false; if (memcmp(peermd, md, mdlen) != 0) return false; return true; }
bool SSLConnection::X509_cmp (X509 *c, unsigned char *peermd, unsigned int peermdlen) { unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; /* * Avoid CPU-intensive digest calculation if the certificates are not * even remotely equal. */ if (X509_subject_name_cmp (cert, c) != 0 || X509_issuer_name_cmp (cert, c) != 0) return false; if (!X509_digest (c, EVP_sha1(), md, &mdlen) || peermdlen != mdlen) return false; if (memcmp(peermd, md, mdlen) != 0) return false; return false; }