/* This callback is called for every certificate in a chain. ok is true if OpenSSL's internal verification has verified the certificate. We don't change anything about the verification, we only need access to the certificates to provide diagnostics. */ static int verify_callback(int ok, X509_STORE_CTX *store) { X509 *cert = X509_STORE_CTX_get_current_cert(store); int err = X509_STORE_CTX_get_error(store); /* Print the subject, issuer, and fingerprint depending on the verbosity level. */ if ((!ok && o.verbose) || o.debug > 1) { char digest_buf[SHA1_STRING_LENGTH + 1]; loguser("Subject: "); X509_NAME_print_ex_fp(stderr, X509_get_subject_name(cert), 0, XN_FLAG_COMPAT); loguser_noprefix("\n"); loguser("Issuer: "); X509_NAME_print_ex_fp(stderr, X509_get_issuer_name(cert), 0, XN_FLAG_COMPAT); loguser_noprefix("\n"); assert(ssl_cert_fp_str_sha1(cert, digest_buf, sizeof(digest_buf)) != NULL); loguser("SHA-1 fingerprint: %s\n", digest_buf); } if (!ok && o.verbose) { loguser("Certificate verification failed (%s).\n", X509_verify_cert_error_string(err)); } return ok; }
void describeCertificate(int i, X509 *cert) { fprintf(stderr,"%1d: Subject: ", i); X509_NAME_print_ex_fp(stderr,X509_get_subject_name(cert), 0, XN_FLAG_ONELINE); fprintf(stderr,"\n"); fprintf(stderr," Issuer: "); X509_NAME_print_ex_fp(stderr,X509_get_issuer_name(cert), 0, XN_FLAG_ONELINE); fprintf(stderr,"\n"); }
static RD_BOOL tls_verify(SSL *connection, const char *server) { /* TODO: Check for eku extension with server authentication purpose */ RD_BOOL verified = False; X509 *server_cert = NULL; int ret; server_cert = SSL_get_peer_certificate(connection); if (!server_cert) { printf("ssl_verify: failed to get the server SSL certificate\n"); goto exit; } ret = SSL_get_verify_result(connection); if (ret != X509_V_OK) { printf("ssl_verify: error %d (see 'man 1 verify' for more information)\n", ret); printf("certificate details:\n Subject:\n"); X509_NAME_print_ex_fp(stdout, X509_get_subject_name(server_cert), 4, XN_FLAG_MULTILINE); printf("\n Issued by:\n"); X509_NAME_print_ex_fp(stdout, X509_get_issuer_name(server_cert), 4, XN_FLAG_MULTILINE); printf("\n"); } else { verified = tls_verify_peer_identity(server_cert, server); } exit: if (!verified) printf("The server could not be authenticated. Connection security may be compromised!\n"); if (server_cert) { X509_free(server_cert); server_cert = NULL; } return verified; }
/***************************************************************************************** * Authorization routines *****************************************************************************************/ int ossl_verify_cb (int ok, X509_STORE_CTX *ctx) { int cert_error = X509_STORE_CTX_get_error(ctx); X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx); EST_LOG_INFO("enter function: ok=%d cert_error=%d", ok, cert_error); if (!ok) { if (current_cert) { X509_NAME_print_ex_fp(stdout, X509_get_subject_name(current_cert), 0, XN_FLAG_ONELINE); printf("\n"); } EST_LOG_INFO("%serror %d at %d depth lookup: %s", X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "", cert_error, X509_STORE_CTX_get_error_depth(ctx), X509_verify_cert_error_string(cert_error)); switch (cert_error) { case X509_V_ERR_UNABLE_TO_GET_CRL: /* * We've enabled CRL checking in the TLS stack. If * the application hasn't loaded a CRL, then this * verify error can occur. The peer's cert is valid, * but we can't confirm if it was revoked. We'll * warn the application. */ EST_LOG_WARN("No CRL loaded, TLS peer will be allowed."); ok = 1; break; case X509_V_ERR_NO_EXPLICIT_POLICY: case X509_V_ERR_CERT_HAS_EXPIRED: /* since we are just checking the certificates, it is * ok if they are self signed. But we should still warn * the user. */ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: /* Continue after extension errors too */ case X509_V_ERR_INVALID_CA: case X509_V_ERR_INVALID_NON_CA: case X509_V_ERR_PATH_LENGTH_EXCEEDED: case X509_V_ERR_INVALID_PURPOSE: case X509_V_ERR_CRL_HAS_EXPIRED: case X509_V_ERR_CRL_NOT_YET_VALID: case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: case X509_V_ERR_CERT_REVOKED: default: EST_LOG_WARN("Certificate verify failed (reason=%d)", cert_error); break; } return ok; } return (ok); }
int main(int argc, char *argv[]) { char *port = "*:4433"; BIO *ssl_bio, *tmp; SSL_CTX *ctx; SSL_CONF_CTX *cctx; char buf[512]; BIO *in = NULL; int ret = 1, i; char **args = argv + 1; int nargs = argc - 1; SSL_load_error_strings(); /* Add ciphers and message digests */ OpenSSL_add_ssl_algorithms(); ctx = SSL_CTX_new(SSLv23_server_method()); cctx = SSL_CONF_CTX_new(); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); while (*args && **args == '-') { int rv; /* Parse standard arguments */ rv = SSL_CONF_cmd_argv(cctx, &nargs, &args); if (rv == -3) { fprintf(stderr, "Missing argument for %s\n", *args); goto err; } if (rv < 0) { fprintf(stderr, "Error in command %s\n", *args); ERR_print_errors_fp(stderr); goto err; } /* If rv > 0 we processed something so proceed to next arg */ if (rv > 0) continue; /* Otherwise application specific argument processing */ if (strcmp(*args, "-port") == 0) { port = args[1]; if (port == NULL) { fprintf(stderr, "Missing -port argument\n"); goto err; } args += 2; nargs -= 2; continue; } else { fprintf(stderr, "Unknown argument %s\n", *args); goto err; } } if (!SSL_CONF_CTX_finish(cctx)) { fprintf(stderr, "Finish error\n"); ERR_print_errors_fp(stderr); goto err; } #ifdef ITERATE_CERTS /* * Demo of how to iterate over all certificates in an SSL_CTX structure. */ { X509 *x; int rv; rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST); while (rv) { X509 *x = SSL_CTX_get0_certificate(ctx); X509_NAME_print_ex_fp(stdout, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); printf("\n"); rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT); } fflush(stdout); } #endif /* Setup server side SSL bio */ ssl_bio = BIO_new_ssl(ctx, 0); if ((in = BIO_new_accept(port)) == NULL) goto err; /* * This means that when a new connection is accepted on 'in', The ssl_bio * will be 'duplicated' and have the new socket BIO push into it. * Basically it means the SSL BIO will be automatically setup */ BIO_set_accept_bios(in, ssl_bio); again: /* * The first call will setup the accept socket, and the second will get a * socket. In this loop, the first actual accept will occur in the * BIO_read() function. */ if (BIO_do_accept(in) <= 0) goto err; for (;;) { i = BIO_read(in, buf, 512); if (i == 0) { /* * If we have finished, remove the underlying BIO stack so the * next time we call any function for this BIO, it will attempt * to do an accept */ printf("Done\n"); tmp = BIO_pop(in); BIO_free_all(tmp); goto again; } if (i < 0) goto err; fwrite(buf, 1, i, stdout); fflush(stdout); } ret = 0; err: if (ret) { ERR_print_errors_fp(stderr); } BIO_free(in); exit(ret); return (!ret); }
int cgiMain() { static char title[256] = ""; static char subtitle[256] = ""; char sorting[16] = "desc"; time_t now = time(NULL); time_t start = time(NULL); time_t expiration = time(NULL); double available_secs = 0; double remaining_secs = 0; struct dirent **certstore_files = NULL; int pagenumber = 1; int certcounter = 0; int tempcounter = 0; int pagecounter = 0; int dispcounter = 0; int dispmaxlines = 0; int certvalidity = 0; div_t disp_calc; div_t oddline_calc; double percent = 0; cert = X509_new(); certsubject = X509_NAME_new(); char **form_data = NULL; /* string array for query data */ /* get the current time */ now = time(NULL); /* ------------------------------------------------------------------------- * * If we are called without arguments, we display the cert search criteria * * ------------------------------------------------------------------------- */ if (cgiFormEntries(&form_data) != cgiFormSuccess) int_error("Error: Could not retrieve CGI form data."); if(form_data[0] == NULL) { start_tm = *gmtime(&now); snprintf(title, sizeof(title), "Search existing Certificates"); pagehead(title); fprintf(cgiOut, "<form action=\"certsearch.cgi\" method=\"get\">"); fprintf(cgiOut, "<table>"); /* Search for Subject String */ fprintf(cgiOut, "<tr><th colspan=\"5\">Search by Name</th></tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th class=\"cnt\" rowspan=\"2\">\n"); fprintf(cgiOut, "<input type=\"radio\" value=\"dn\" name=\"search\" />"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<td class=\"type\">\n"); fprintf(cgiOut, "Distinguished Name Field:"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"center\">\n"); fprintf(cgiOut, "<select name=\"field\">"); fprintf(cgiOut, "<option value=\"countryName\">Country</option>"); fprintf(cgiOut, "<option value=\"stateOrProvinceName\">State</option>"); fprintf(cgiOut, "<option value=\"localityName\">Location</option>"); fprintf(cgiOut, "<option value=\"organizationName\">Organisation</option>"); fprintf(cgiOut, "<option value=\"organizationalUnitName\">Department</option>"); fprintf(cgiOut, "<option value=\"emailAddress\">E-Mail Addr</option>"); fprintf(cgiOut, "<option selected=\"selected\" value=\"commonName\">Common Name</option>"); fprintf(cgiOut, "<option value=\"surname\">Surname</option>"); fprintf(cgiOut, "<option value=\"givenName\">Given Name</option>"); fprintf(cgiOut, "</select>"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"type\">\n"); fprintf(cgiOut, "Search String<br />[20 chars max]:"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"center\">\n"); fprintf(cgiOut, "<input type=\"text\" size=\"15\" name=\"dnvalue\" value=\"changeme.com\" />"); fprintf(cgiOut, "</td>"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<td class=\"desc\" colspan=\"4\">\n"); fprintf(cgiOut, "Search for certificates that have the given string in the selected DN field. "); fprintf(cgiOut, "The search is case sensitive, so results for country=us can be different from country=US and country=Us."); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "</tr>\n"); /* Search for Expiration Date */ fprintf(cgiOut, "<tr><th colspan=\"5\">Search by Expiration Date</th></tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th class=\"cnt\" rowspan=\"2\">\n"); fprintf(cgiOut, "<input type=\"radio\" value=\"exp\" name=\"search\" checked=\"checked\" />"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<td class=\"type\">\n"); fprintf(cgiOut, "Expiration Date is<br />between Start Date:"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"center\">\n"); strftime(membio_buf, sizeof(membio_buf), "%d.%m.%Y", &start_tm); fprintf(cgiOut, "<input type=\"text\" size=\"9\" name=\"exp_startdate\" value=\"%s\" /> ", membio_buf); strftime(membio_buf, sizeof(membio_buf), "%H:%M", &start_tm); fprintf(cgiOut, "<input type=\"text\" size=\"3\" name=\"exp_starttime\" value=\"%s\" />", membio_buf); fprintf(cgiOut, "</td>"); fprintf(cgiOut, "<td class=\"type\">\n"); fprintf(cgiOut, "and End Date<br />[default 90 days]:"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"center\">\n"); /* set second time 3 months (90 days) into the future: 86400s/d*90d=7776000s */ expiration = now + 7776000; expiration_tm = *gmtime(&expiration); strftime(membio_buf, sizeof(membio_buf), "%d.%m.%Y", &expiration_tm); fprintf(cgiOut, "<input type=\"text\" size=\"9\" name=\"exp_enddate\" value=\"%s\" /> ", membio_buf); strftime(membio_buf, sizeof(membio_buf), "%H:%M", &expiration_tm); fprintf(cgiOut, "<input type=\"text\" size=\"3\" name=\"exp_endtime\" value=\"%s\" />", membio_buf); fprintf(cgiOut, "</td>"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<td class=\"desc\" colspan=\"4\">\n"); fprintf(cgiOut, "Search for certificates that expire(d) between the selected start and end date. "); fprintf(cgiOut, "By default, the search is pre-set to find certificates that expire in the next 3 months."); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "</tr>\n"); /* Search for Enabled Date */ fprintf(cgiOut, "<tr><th colspan=\"5\">Search by Creation Date</th></tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th class=\"cnt\" rowspan=\"2\">\n"); fprintf(cgiOut, "<input type=\"radio\" value=\"ena\" name=\"search\" />"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<td class=\"type\">\n"); fprintf(cgiOut, "Enabled Date is<br />between Start Date:"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"center\">\n"); /* set second time 3 months (90 days) into the past: 86400s/d*90d=7776000s */ expiration = now - 7776000; expiration_tm = *gmtime(&expiration); strftime(membio_buf, sizeof(membio_buf), "%d.%m.%Y", &expiration_tm); fprintf(cgiOut, "<input type=\"text\" size=\"9\" name=\"ena_startdate\" value=\"%s\" /> ", membio_buf); strftime(membio_buf, sizeof(membio_buf), "%H:%M", &expiration_tm); fprintf(cgiOut, "<input type=\"text\" size=\"3\" name=\"ena_starttime\" value=\"%s\" />", membio_buf); fprintf(cgiOut, "</td>"); fprintf(cgiOut, "<td class=\"type\">\n"); fprintf(cgiOut, "and End Date<br />[default now]:"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"center\">\n"); strftime(membio_buf, sizeof(membio_buf), "%d.%m.%Y", &start_tm); fprintf(cgiOut, "<input type=\"text\" size=\"9\" name=\"ena_enddate\" value=\"%s\" /> ", membio_buf); strftime(membio_buf, sizeof(membio_buf), "%H:%M", &start_tm); fprintf(cgiOut, "<input type=\"text\" size=\"3\" name=\"ena_endtime\" value=\"%s\" />", membio_buf); fprintf(cgiOut, "</td>"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<td class=\"desc\" colspan=\"4\">\n"); fprintf(cgiOut, "Search for certificates that become valid between the selected start and end date. "); fprintf(cgiOut, "By default, the search is pre-set to show certificates created in the past 3 months."); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "</tr>\n"); /* Search for Revocation Date */ fprintf(cgiOut, "<tr><th colspan=\"5\">Search by Revocation Date</th></tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th class=\"cnt\" rowspan=\"2\">\n"); fprintf(cgiOut, "<input type=\"radio\" value=\"rev\" name=\"search\" />"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<td class=\"type\">\n"); fprintf(cgiOut, "Revocation Date is<br />between Start Date:"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"center\">\n"); /* set second time 3 months (90 days) into the past: 86400s/d*90d=7776000s */ expiration = now - 7776000; expiration_tm = *gmtime(&expiration); strftime(membio_buf, sizeof(membio_buf), "%d.%m.%Y", &expiration_tm); fprintf(cgiOut, "<input type=\"text\" size=\"9\" name=\"rev_startdate\" value=\"%s\" /> ", membio_buf); strftime(membio_buf, sizeof(membio_buf), "%H:%M", &expiration_tm); fprintf(cgiOut, "<input type=\"text\" size=\"3\" name=\"rev_starttime\" value=\"%s\"/>", membio_buf); fprintf(cgiOut, "</td>"); fprintf(cgiOut, "<td class=\"type\">\n"); fprintf(cgiOut, "and End Date<br />[now]:"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"center\">\n"); strftime(membio_buf, sizeof(membio_buf), "%d.%m.%Y", &start_tm); fprintf(cgiOut, "<input type=\"text\" size=\"9\" name=\"rev_enddate\" value=\"%s\" /> ", membio_buf); strftime(membio_buf, sizeof(membio_buf), "%H:%M", &start_tm); fprintf(cgiOut, "<input type=\"text\" size=\"3\" name=\"rev_endtime\" value=\"%s\" />", membio_buf); fprintf(cgiOut, "</td>"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<td class=\"desc\" colspan=\"4\">\n"); fprintf(cgiOut, "Search for certificates that have been revoked between the selected start and end date. "); fprintf(cgiOut, " By default, the search is pre-set to show certificates revoked in the past 3 months."); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "</tr>\n"); /* Search for Serial Number */ fprintf(cgiOut, "<tr><th colspan=\"5\">Search by Serial Number</th></tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th class=\"cnt\" rowspan=\"2\">\n"); fprintf(cgiOut, "<input type=\"radio\" value=\"ser\" name=\"search\" />"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<td class=\"type\">\n"); fprintf(cgiOut, "Serial Number is<br />between Start Serial:"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"center\">\n"); fprintf(cgiOut, "<input type=\"text\" size=\"14\" name=\"startserial\" "); fprintf(cgiOut, "value=\"%s\" style=\"text-align:right;\" />", startserstr); fprintf(cgiOut, "</td>"); fprintf(cgiOut, "<td class=\"type\">\n"); fprintf(cgiOut, "and End Serial<br />[max 10e11]:"); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "<td class=\"center\">\n"); fprintf(cgiOut, "<input type=\"text\" size=\"14\" name=\"endserial\" "); fprintf(cgiOut, "value=\"%s\" style=\"text-align:right;\" />", endserstr); fprintf(cgiOut, "</td>"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<td class=\"desc\" colspan=\"4\">\n"); fprintf(cgiOut, "Search for certificates whose serial number is between the given "); fprintf(cgiOut, "start and end serial number in decimal format. To find a particular certificate, set start and end serial to be equal."); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th colspan=\"5\">"); fprintf(cgiOut, "<input type=\"submit\" value=\"Search Certificates\" />"); fprintf(cgiOut, "</th>"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "</table>\n"); fprintf(cgiOut, "</form>\n"); pagefoot(); } else { /* ------------------------------------------------------------------- * * check if we got the CGI form data * * --------------------------------------------------------------------*/ if ( cgiFormString("search", search, sizeof(search)) != cgiFormSuccess ) int_error("Error retrieving CGI form search type."); else { if (strcmp(search, "dn") == 0) { if ( cgiFormString("field", field, sizeof(field)) != cgiFormSuccess ) int_error("Error retrieving CGI form DN search field information."); if ( cgiFormString("dnvalue", dnvalue, sizeof(dnvalue)) != cgiFormSuccess ) int_error("Error retrieving CGI form DN search dnvalue information."); snprintf(title, sizeof(title), "Search Certs by Subject"); snprintf(subtitle, sizeof(subtitle), "Certificates with DN %s=%s", field, dnvalue); } else if (strcmp(search, "exp") == 0) { if ( cgiFormString("exp_startdate", exp_startdate, sizeof(exp_startdate)) != cgiFormSuccess ) int_error("Error retrieving CGI form expiration start date."); if ( cgiFormString("exp_starttime", exp_starttime, sizeof(exp_starttime)) != cgiFormSuccess ) int_error("Error retrieving CGI form expiration start time."); if ( cgiFormString("exp_enddate", exp_enddate, sizeof(exp_enddate)) != cgiFormSuccess ) int_error("Error retrieving CGI form expiration end date."); if ( cgiFormString("exp_endtime", exp_endtime, sizeof(exp_endtime)) != cgiFormSuccess ) int_error("Error retrieving CGI form expiration end time."); strncat(exp_startstr, exp_startdate, sizeof(exp_startstr)-1); strncat(exp_startstr, " ", 1); /* add a space between date and time */ strncat(exp_startstr, exp_starttime, sizeof(exp_startstr)-strlen(exp_startstr)-1); strncat(exp_endstr, exp_enddate, sizeof(exp_endstr)-1); strncat(exp_endstr, " ", 1); /* add a space between date and time */ strncat(exp_endstr, exp_endtime, sizeof(exp_endstr)-strlen(exp_endstr)-1); snprintf(title, sizeof(title), "Search Certs by Expiration"); snprintf(subtitle, sizeof(subtitle), "Certificates with expiration between %s and %s", exp_startstr, exp_endstr); } else if (strcmp(search, "ena") == 0) { if ( cgiFormString("ena_startdate", ena_startdate, sizeof(ena_startdate)) != cgiFormSuccess ) int_error("Error retrieving CGI form enable start date."); if ( cgiFormString("ena_starttime", ena_starttime, sizeof(ena_starttime)) != cgiFormSuccess ) int_error("Error retrieving CGI form enable start time."); if ( cgiFormString("ena_enddate", ena_enddate, sizeof(ena_enddate)) != cgiFormSuccess ) int_error("Error retrieving CGI form enable end date."); if ( cgiFormString("ena_endtime", ena_endtime, sizeof(ena_endtime)) != cgiFormSuccess ) int_error("Error retrieving CGI form enable end time."); strncat(ena_startstr, ena_startdate, sizeof(ena_startstr)-1); strncat(ena_startstr, " ", 1); /* add a space between date and time */ strncat(ena_startstr, ena_starttime, sizeof(ena_startstr)-strlen(ena_startstr)-1); strncat(ena_endstr, ena_enddate, sizeof(ena_endstr)-1); strncat(ena_endstr, " ", 1); /* add a space between date and time */ strncat(ena_endstr, ena_endtime, sizeof(ena_endstr)-strlen(ena_endstr)-1); snprintf(title, sizeof(title), "Search Certs by Start Date"); snprintf(subtitle, sizeof(subtitle), "Certificates with start date between %s and %s", ena_startstr, ena_endstr); } else if (strcmp(search, "rev") == 0) { if ( cgiFormString("rev_startdate", rev_startdate, sizeof(rev_startdate)) != cgiFormSuccess ) int_error("Error retrieving CGI form enable start date."); if ( cgiFormString("rev_starttime", rev_starttime, sizeof(rev_starttime)) != cgiFormSuccess ) int_error("Error retrieving CGI form enable start time."); if ( cgiFormString("rev_enddate", rev_enddate, sizeof(rev_enddate)) != cgiFormSuccess ) int_error("Error retrieving CGI form enable end date."); if ( cgiFormString("rev_endtime", rev_endtime, sizeof(rev_endtime)) != cgiFormSuccess ) int_error("Error retrieving CGI form enable end time."); strncat(rev_startstr, rev_startdate, sizeof(rev_startstr)-1); strncat(rev_startstr, " ", 1); /* add a space between date and time */ strncat(rev_startstr, rev_starttime, sizeof(rev_startstr)-strlen(rev_startstr)-1); strncat(rev_endstr, rev_enddate, sizeof(rev_endstr)-1); strncat(rev_endstr, " ", 1); /* add a space between date and time */ strncat(rev_endstr, rev_endtime, sizeof(rev_endstr)-strlen(rev_endstr)-1); snprintf(title, sizeof(title), "Search Revoked Certificates"); snprintf(subtitle, sizeof(subtitle), "Certificates revoked between %s and %s", rev_startstr, rev_endstr); } else if (strcmp(search, "ser") == 0) { if ( cgiFormString("startserial", startserstr, sizeof(startserstr)) != cgiFormSuccess ) int_error("Error retrieving CGI form start serial value."); if ( cgiFormString("endserial", endserstr, sizeof(endserstr)) != cgiFormSuccess ) int_error("Error retrieving CGI form end serial value."); snprintf(title, sizeof(title), "Search Certs by Serial Number"); snprintf(subtitle, sizeof(subtitle), "Certificates with serial number between %s and %s", startserstr, endserstr); } else int_error("Error CGI form retrieving a valid search type."); } /* -------------------------------------------------------------------------- * * We got CGI arguments, first we get a list of .pem files from the cert dir * * ---------------------------------------------------------------------------*/ certcounter = scandir(CACERTSTORE, &certstore_files, file_select, hexsort); // It can happen that our search does not return any certs. This is not an error. //if(certcounter<=0) int_error("Error: No certificate files found."); /* -------------------------------------------------------------------------- * * calculate how many pages we get with MAXCERTDISPLAY * * ---------------------------------------------------------------------------*/ if(certcounter<=MAXCERTDISPLAY) pagecounter = 1; else { disp_calc = div(certcounter, MAXCERTDISPLAY); /* if the count of certs divided by MAXCERTDISPLAY has no remainder */ if(disp_calc.rem == 0) pagecounter = disp_calc.quot; /* with a remainder, we must prepare an extra page for the rest */ else pagecounter = disp_calc.quot +1; } /* -------------------------------------------------------------------------- * * Check if we have been subsequently called with a pagenumber & sort request * * ---------------------------------------------------------------------------*/ if(cgiFormInteger("page", &pagenumber, 1) == cgiFormSuccess) if(pagenumber > pagecounter || pagenumber <=0) int_error("Error: Page does not exist."); if(cgiFormString("sort", sorting, sizeof(sorting)) != cgiFormSuccess) strncpy(sorting, "desc", sizeof(sorting)); /* -------------------------------------------------------------------------- * * now we know how many certs we have in total and we can build the page(s). * * For every MAXCERTDISPLAY certs we start a new page and cycle through by * * calling ourself with the requested certs in range. * * ---------------------------------------------------------------------------*/ if(strcmp(sorting, "asc") == 0) { if(certcounter <= MAXCERTDISPLAY) { dispmaxlines = certcounter; tempcounter = 0; } else if(pagenumber == pagecounter && ( pagecounter * MAXCERTDISPLAY) - certcounter != 0) { tempcounter = (pagecounter * MAXCERTDISPLAY) - MAXCERTDISPLAY; dispmaxlines = certcounter - ((pagecounter-1) * MAXCERTDISPLAY); } else { tempcounter = (pagenumber * MAXCERTDISPLAY) - MAXCERTDISPLAY; dispmaxlines = MAXCERTDISPLAY; } } if(strcmp(sorting, "desc") == 0) { if(certcounter <= MAXCERTDISPLAY) { dispmaxlines = certcounter; tempcounter = certcounter; } else if(pagenumber == pagecounter && ( pagecounter * MAXCERTDISPLAY) - certcounter != 0) { tempcounter = certcounter - ((pagecounter-1) * MAXCERTDISPLAY); dispmaxlines = certcounter - ((pagecounter-1) * MAXCERTDISPLAY); } else { tempcounter = certcounter - (pagenumber*MAXCERTDISPLAY) + MAXCERTDISPLAY; dispmaxlines = MAXCERTDISPLAY; } } /* -------------------------------------------------------------------------- * * start the html output * * ---------------------------------------------------------------------------*/ pagehead(title); //debugging only: //printf("Number of certs: %d\n", certcounter); //printf("Num tempcounter: %d\n", tempcounter); //printf("Number of pages: %d\n", pagecounter); //printf("Div Quotient: %d\n", disp_calc.quot); //printf("Div Remainder: %d\n", disp_calc.rem); //fprintf(cgiOut, "</BODY></HTML>\n"); //exit(0); /* -------------------------------------------------------------------------- * * start the form output * * ---------------------------------------------------------------------------*/ fprintf(cgiOut, "<h3>%s</h3>\n", subtitle); fprintf(cgiOut, "<p></p>\n"); fprintf(cgiOut, "<table>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th width=\"20\">"); fprintf(cgiOut, "#"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<th width=\"495\">"); fprintf(cgiOut, "Certificate Subject Information"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<th width=\"60\" colspan=\"2\">"); fprintf(cgiOut, "Expires"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<th width=\"65\">"); fprintf(cgiOut, "Action"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "</tr>\n"); /* if our search did not return any certs, we display a note instead */ if(certcounter<=0) { fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<td class=\"even\" colspan=\"5\">"); fprintf(cgiOut, "Could not find any certificates for the given search criteria."); fprintf(cgiOut, "</td>\n"); fprintf(cgiOut, "</tr>\n"); } for(dispcounter=0; dispcounter < dispmaxlines; dispcounter++) { /* zero certificate values and flags */ certvalidity = 0; percent = 0; available_secs = 0; remaining_secs = 0; cert = X509_new(); certsubject = X509_NAME_new(); if(strcmp(sorting, "desc") == 0) tempcounter--; snprintf(certfilestr, sizeof(certfilestr), "%s/%s", CACERTSTORE, certstore_files[tempcounter]->d_name); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th rowspan=\"2\">"); fprintf(cgiOut, "%d", tempcounter+1); fprintf(cgiOut, "</th>\n"); oddline_calc = div(tempcounter+1, 2); if(oddline_calc.rem) fprintf(cgiOut, "<td rowspan=\"2\" class=\"odd\">"); else fprintf(cgiOut, "<td rowspan=\"2\" class=\"even\">"); if ( (certfile = fopen(certfilestr, "r")) != NULL) { PEM_read_X509(certfile, &cert, NULL, NULL); /* ---------------------------------------------------------- * * Display the subject data. Use the UTF-8 flag to show * * Japanese Kanji. This also needs the separator flag to work * * ---------------------------------------------------------- */ certsubject = X509_get_subject_name(cert); X509_NAME_print_ex_fp(cgiOut, certsubject, 0, ASN1_STRFLGS_UTF8_CONVERT|XN_FLAG_SEP_CPLUS_SPC); /* store certificate start date for later eval */ start_date = X509_get_notBefore(cert); /* store certificate expiration date for later eval */ expiration_date = X509_get_notAfter(cert); /* check the start and end dates in the cert */ if (X509_cmp_current_time (X509_get_notBefore (cert)) >= 0) /* flag the certificate as not valid yet */ certvalidity = 0; else if (X509_cmp_current_time (X509_get_notAfter (cert)) <= 0) /* flag the certificate as expired */ certvalidity = 0; else /* flag the certificate is still valid */ certvalidity = 1; fclose(certfile); } else fprintf(cgiOut, "Error: Can't open certificate file %s for reading.", certfilestr); fprintf(cgiOut, "</td>\n"); if(certvalidity == 0) { /* expiration bar display column */ fprintf(cgiOut, "<th rowspan=\"2\">\n"); fprintf(cgiOut, "<table class=\"led\">\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, "</table>\n"); fprintf(cgiOut, "</th>\n"); /* remaining days before expiration column */ fprintf(cgiOut, "<th class=\"exnok\" rowspan=\"2\">"); fprintf(cgiOut, "Inval.<br />/Expd"); fprintf(cgiOut, "</th>\n"); } if(certvalidity == 1) { /* ------ START get the certificate lifetime in seconds ------ */ /* copy the start date into a string */ membio = BIO_new(BIO_s_mem()); ASN1_TIME_print(membio, start_date); BIO_gets(membio, membio_buf, sizeof(membio_buf)); BIO_free(membio); /* parse the start date string into a time struct */ memset (&start_tm, '\0', sizeof(start_tm)); strptime(membio_buf, "%h %d %T %Y %z", &start_tm); start = mktime(&start_tm); /* ------ START get the certificate remaining time in seconds ------ */ /* copy the expiration date into a string */ membio = BIO_new(BIO_s_mem()); ASN1_TIME_print(membio, expiration_date); BIO_gets(membio, membio_buf, sizeof(membio_buf)); BIO_free(membio); /* parse the expiration date string into a time struct */ memset (&expiration_tm, '\0', sizeof(expiration_tm)); strptime(membio_buf, "%h %d %T %Y %z", &expiration_tm); /* get the current time */ expiration = mktime(&expiration_tm); /* get the time difference between expiration time and current time */ remaining_secs = difftime(expiration, now); /* ------ END get the certificate remaining time in seconds ------ */ /* get the time difference between start and expiration time */ available_secs = difftime(expiration, start); /* ------ END get the certificate lifetime in seconds ------ */ /* ------ START calculate percentage of lifetime left ------ */ /* remaining_secs *100 */ /* ------------------- = X, rounded down with floor() */ /* available_secs */ percent = floor((remaining_secs*100)/available_secs); /* ------ END calculate percentage of lifetime left ------ */ /* expiration bar display column */ fprintf(cgiOut, "<th rowspan=\"2\">"); fprintf(cgiOut, "<table class=\"led\">\n"); if (percent >= 90) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=#00FF00></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 80) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=#00FF33></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 70) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=#99FF33></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 60) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=#FFFF00></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 50) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=#FFCC00></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 40) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=#FF9900></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 30) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=#FF6600></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 20) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=#FF3300></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 10) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=#FF0000></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, "</table>\n"); fprintf(cgiOut, "</th>"); /* remaining days before expiration column */ //fprintf(cgiOut, membio_buf); if (percent < 10) fprintf(cgiOut, "<th class=\"exnok\" rowspan=\"2\">\n"); else fprintf(cgiOut, "<th class=\"exok\" rowspan=\"2\">\n"); if(floor(remaining_secs/63072000) > 0) fprintf(cgiOut, "%.f<br />years", remaining_secs/31536000); else if(floor(remaining_secs/86400) > 0 ) fprintf(cgiOut, "%.f<br />days", remaining_secs/86400); else if(floor(remaining_secs/3600) > 0 ) fprintf(cgiOut, "%.f<br />hours", remaining_secs/3600); else if(floor(remaining_secs/60) > 0 ) fprintf(cgiOut, "%.f<br />mins", remaining_secs/60); else fprintf(cgiOut, "%.f<br />secs", remaining_secs); fprintf(cgiOut, "</th>\n"); } /* action column */ fprintf(cgiOut, "<th>"); fprintf(cgiOut, "<form action=\"getcert.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"cfilename\" "); fprintf(cgiOut, "value=\"%s\" />\n", certstore_files[tempcounter]->d_name); fprintf(cgiOut, "<input type=\"hidden\" name=\"format\" value=\"pem\" />\n"); fprintf(cgiOut, "<input class=\"getcert\" type=\"submit\" value=\"Detail\" />\n"); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th>"); fprintf(cgiOut, "<form action=\"getcert.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"cfilename\" "); fprintf(cgiOut, "value=\"%s\" />\n", certstore_files[tempcounter]->d_name); fprintf(cgiOut, "<input type=\"hidden\" name=\"format\" value=\"text\" />\n"); fprintf(cgiOut, "<input class=\"getcert\" type=\"submit\" value=\"Renew\" />\n"); fprintf(cgiOut, "</form>"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "</tr>\n"); if(strcmp(sorting, "asc") == 0) tempcounter++; } fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th colspan=\"5\">"); fprintf(cgiOut, "Total # of certs: %d | ", certcounter); fprintf(cgiOut, "Page %d of %d", pagenumber, pagecounter); fprintf(cgiOut, "</th>"); fprintf(cgiOut, "</tr>"); fprintf(cgiOut, "</table>\n"); fprintf(cgiOut, "<p></p>\n"); fprintf(cgiOut, "<table>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th>"); fprintf(cgiOut, "<form action=\"certsearch.cgi\" method=\"post\">"); fprintf(cgiOut, "<input type=\"hidden\" name=\"sort\" "); fprintf(cgiOut, "value=\"desc\" />\n"); resubmit(); fprintf(cgiOut, "<input type=\"submit\" name=\"sort\""); fprintf(cgiOut, " value=\"Latest Certs first\" />"); fprintf(cgiOut, "</form>"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<th>"); fprintf(cgiOut, "<form action=\"certsearch.cgi\" method=\"post\">"); fprintf(cgiOut, "<input type=\"hidden\" name=\"sort\" "); fprintf(cgiOut, "value=\"asc\">\n"); resubmit(); fprintf(cgiOut, "<input type=\"submit\" name=\"sort\""); fprintf(cgiOut, " value=\"Oldest Certs first\">"); fprintf(cgiOut, "</form>"); fprintf(cgiOut, "</th>\n"); // filler 1 fprintf(cgiOut, "<th width=\"15\">"); fprintf(cgiOut, " "); fprintf(cgiOut, "</th>\n"); // goto page 1 fprintf(cgiOut, "<th width=\"5\">"); fprintf(cgiOut, "<form action=\"certsearch.cgi\" method=\"post\">"); resubmit(); fprintf(cgiOut, "<input type=\"submit\" value=\"<<\" />"); fprintf(cgiOut, "</form>"); fprintf(cgiOut, "</th>\n"); // goto page before fprintf(cgiOut, "<th width=\"5\">"); fprintf(cgiOut, "<form action=\"certsearch.cgi\" method=\"post\">"); fprintf(cgiOut, "<input type=\"hidden\" name=\"certcounter\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", certcounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"pagecounter\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", pagecounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"page\" "); fprintf(cgiOut, "value=\""); tempcounter = 0; if(pagenumber > 1) tempcounter = pagenumber - 1; else tempcounter = 1; fprintf(cgiOut, "%d", tempcounter); fprintf(cgiOut, "\" />\n"); resubmit(); fprintf(cgiOut, "<input type=\"submit\" value=\"< 1\">"); fprintf(cgiOut, "</form>"); fprintf(cgiOut, "</th>\n"); // goto page after fprintf(cgiOut, "<th width=\"5\">"); fprintf(cgiOut, "<form action=\"certsearch.cgi\" method=\"post\">"); fprintf(cgiOut, "<input type=\"hidden\" name=\"certcounter\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", certcounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"pagecounter\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", pagecounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"page\" "); fprintf(cgiOut, "value=\""); tempcounter = 0; if(pagecounter > pagenumber) tempcounter = pagenumber + 1; else tempcounter = pagecounter; fprintf(cgiOut, "%d", tempcounter); fprintf(cgiOut, "\" />\n"); resubmit(); fprintf(cgiOut, "<input type=\"submit\" value=\"1 >\" />"); fprintf(cgiOut, "</form>"); fprintf(cgiOut, "</th>\n"); // goto last page fprintf(cgiOut, "<th width=\"5\">"); fprintf(cgiOut, "<form action=\"certsearch.cgi\" method=\"post\">"); fprintf(cgiOut, "<input type=\"hidden\" name=\"certcounter\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", certcounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"pagecounter\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", pagecounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"page\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", pagecounter); fprintf(cgiOut, "\" />\n"); resubmit(); fprintf(cgiOut, "<input type=\"submit\" value=\">>\" />"); fprintf(cgiOut, "</form>"); fprintf(cgiOut, "</th>\n"); // goto page number fprintf(cgiOut, "<th width=\"120\">\n"); fprintf(cgiOut, "<form class=\"setpage\" action=\"certsearch.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"certcounter\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", certcounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"pagecounter\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", pagecounter); fprintf(cgiOut, "\" />\n"); resubmit(); fprintf(cgiOut, "<input class=\"goto\" type=\"submit\" value=\"Goto\" />\n"); fprintf(cgiOut, " "); fprintf(cgiOut, "<input class=\"page\" type=\"text\" name=\"page\" "); fprintf(cgiOut, "value=\"%d\" />\n", pagecounter); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "</table>\n"); /* ---------------------------------------------------------------------------* * end the html output * * ---------------------------------------------------------------------------*/ pagefoot(); } return(0); }
static SSL* tls_connect(ioa_socket_raw fd, ioa_addr *remote_addr, int *try_again, int connect_cycle) { int ctxtype = (int)(((unsigned long)random())%root_tls_ctx_num); SSL *ssl; ssl = SSL_NEW(root_tls_ctx[ctxtype]); #if ALPN_SUPPORTED SSL_set_alpn_protos(ssl, kALPNProtos, kALPNProtosLen); #endif if(use_tcp) { SSL_set_fd(ssl, fd); } else { #if !DTLS_SUPPORTED UNUSED_ARG(remote_addr); fprintf(stderr,"ERROR: DTLS is not supported.\n"); exit(-1); #else /* Create BIO, connect and set to already connected */ BIO *bio = BIO_new_dgram(fd, BIO_CLOSE); //bio = BIO_new_socket(fd, BIO_CLOSE); BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &remote_addr->ss); SSL_set_bio(ssl, bio, bio); { struct timeval timeout; /* Set and activate timeouts */ timeout.tv_sec = DTLS_MAX_CONNECT_TIMEOUT; timeout.tv_usec = 0; BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); } set_mtu_df(ssl, fd, remote_addr->ss.sa_family, SOSO_MTU, !use_tcp, clnet_verbose); #endif } SSL_set_max_cert_list(ssl, 655350); if (clnet_verbose) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "call SSL_connect...\n"); int rc = 0; do { do { rc = SSL_connect(ssl); } while (rc < 0 && errno == EINTR); int orig_errno = errno; if (rc > 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: client session connected with cipher %s, method=%s\n",__FUNCTION__, SSL_get_cipher(ssl),turn_get_ssl_method(ssl,NULL)); if(clnet_verbose && SSL_get_peer_certificate(ssl)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "------------------------------------------------------------\n"); X509_NAME_print_ex_fp(stdout, X509_get_subject_name(SSL_get_peer_certificate(ssl)), 1, XN_FLAG_MULTILINE); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n Cipher: %s\n", SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n------------------------------------------------------------\n\n"); } break; } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot connect: rc=%d, ctx=%d\n", __FUNCTION__,rc,ctxtype); switch (SSL_get_error(ssl, rc)) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: if(!dos) usleep(1000); continue; default: { char buf[1025]; TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "errno=%d, err=%d, %s (%d)\n",orig_errno, (int)ERR_get_error(), ERR_error_string(ERR_get_error(), buf), (int)SSL_get_error(ssl, rc)); if(connect_cycle<MAX_TLS_CYCLES) { if(try_again) { SSL_FREE(ssl); *try_again = 1; return NULL; } } exit(-1); } }; } } while (1); if (clnet_verbose && SSL_get_peer_certificate(ssl)) { if(use_tcp) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "------TLS---------------------------------------------------\n"); } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "------DTLS---------------------------------------------------\n"); } X509_NAME_print_ex_fp(stdout, X509_get_subject_name( SSL_get_peer_certificate(ssl)), 1, XN_FLAG_MULTILINE); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n Cipher: %s\n", SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n------------------------------------------------------------\n\n"); } return ssl; }
int cgiMain() { static char title[] = "List of existing Certificates"; char sorting[16] = "desc"; char certfilestr[225] = ""; FILE *certfile = NULL; BIO *membio = NULL; BIO *outbio = NULL; char membio_buf[128] = ""; X509 *cert = NULL; X509_NAME *certsubject = NULL; ASN1_TIME *start_date = NULL; ASN1_TIME *expiration_date = NULL; struct tm start_tm; struct tm expiration_tm; time_t now = time(NULL); time_t start = time(NULL); time_t expiration = time(NULL); double available_secs = 0; double remaining_secs = 0; struct dirent **certstore_files = NULL; int pagenumber = 1; int certcounter = 0; int tempcounter = 0; int pagecounter = 0; int dispcounter = 0; int dispmaxlines = 0; int certvalidity = 0; div_t disp_calc; div_t oddline_calc; double percent = 0; cert = X509_new(); certsubject = X509_NAME_new(); /* -------------------------------------------------------------------------- * * Get the list of .pem files from the cert directory * * ---------------------------------------------------------------------------*/ certcounter = scandir(CACERTSTORE, &certstore_files, file_select, hexsort); if(certcounter<=0) int_error("Error: No certificate files found."); /* -------------------------------------------------------------------------- * * calculate how many pages we get with MAXCERTDISPLAY * * ---------------------------------------------------------------------------*/ if(certcounter<=MAXCERTDISPLAY) pagecounter = 1; else { disp_calc = div(certcounter, MAXCERTDISPLAY); /* if the count of certs divided by MAXCERTDISPLAY has no remainder */ if(disp_calc.rem == 0) pagecounter = disp_calc.quot; /* with a remainder, we must prepare an extra page for the rest */ else pagecounter = disp_calc.quot +1; } /* -------------------------------------------------------------------------- * * Check if we have been subsequently called with a pagenumber & sort request * * ---------------------------------------------------------------------------*/ if(cgiFormInteger("page", &pagenumber, 1) == cgiFormSuccess) if(pagenumber > pagecounter || pagenumber <=0) int_error("Error: Page does not exist."); if(cgiFormString("sort", sorting, sizeof(sorting)) != cgiFormSuccess) strncpy(sorting, "desc", sizeof(sorting)); /* -------------------------------------------------------------------------- * * now we know how many certs we have in total and we can build the page(s). * * For every MAXCERTDISPLAY certs we start a new page and cycle through by * * calling ourself with the requested certs in range. * * ---------------------------------------------------------------------------*/ if(strcmp(sorting, "asc") == 0) { if(certcounter <= MAXCERTDISPLAY) { dispmaxlines = certcounter; tempcounter = 0; } else if(pagenumber == pagecounter && ( pagecounter * MAXCERTDISPLAY) - certcounter != 0) { tempcounter = (pagecounter * MAXCERTDISPLAY) - MAXCERTDISPLAY; dispmaxlines = certcounter - ((pagecounter-1) * MAXCERTDISPLAY); } else { tempcounter = (pagenumber * MAXCERTDISPLAY) - MAXCERTDISPLAY; dispmaxlines = MAXCERTDISPLAY; } } if(strcmp(sorting, "desc") == 0) { if(certcounter <= MAXCERTDISPLAY) { dispmaxlines = certcounter; tempcounter = certcounter; } else if(pagenumber == pagecounter && ( pagecounter * MAXCERTDISPLAY) - certcounter != 0) { tempcounter = certcounter - ((pagecounter-1) * MAXCERTDISPLAY); dispmaxlines = certcounter - ((pagecounter-1) * MAXCERTDISPLAY); } else { tempcounter = certcounter - (pagenumber*MAXCERTDISPLAY) + MAXCERTDISPLAY; dispmaxlines = MAXCERTDISPLAY; } } /* -------------------------------------------------------------------------- * * start the html output * * ---------------------------------------------------------------------------*/ outbio = BIO_new(BIO_s_file()); BIO_set_fp(outbio, cgiOut, BIO_NOCLOSE); pagehead(title); //debugging only: //printf("Number of certs: %d\n", certcounter); //printf("Num tempcounter: %d\n", tempcounter); //printf("Number of pages: %d\n", pagecounter); //printf("Div Quotient: %d\n", disp_calc.quot); //printf("Div Remainder: %d\n", disp_calc.rem); //fprintf(cgiOut, "</BODY></HTML>\n"); //exit(0); /* -------------------------------------------------------------------------- * * start the form output * * ---------------------------------------------------------------------------*/ fprintf(cgiOut, "<table>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th width=\"20\">"); fprintf(cgiOut, "#"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<th width=\"495\">"); fprintf(cgiOut, "Certificate Subject Information"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<th colspan=\"2\" width=\"60\">"); fprintf(cgiOut, "Expiry"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<th width=\"65\">"); fprintf(cgiOut, "Action"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "</tr>\n"); for(dispcounter=0; dispcounter < dispmaxlines; dispcounter++) { /* zero certificate values and flags */ certvalidity = 0; percent = 0; available_secs = 0; remaining_secs = 0; cert = X509_new(); certsubject = X509_NAME_new(); if(strcmp(sorting, "desc") == 0) tempcounter--; snprintf(certfilestr, sizeof(certfilestr), "%s/%s", CACERTSTORE, certstore_files[tempcounter]->d_name); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th rowspan=\"2\">"); fprintf(cgiOut, "%d", tempcounter+1); fprintf(cgiOut, "</th>\n"); oddline_calc = div(tempcounter+1, 2); if(oddline_calc.rem) fprintf(cgiOut, "<td rowspan=\"2\" class=\"odd\">"); else fprintf(cgiOut, "<td rowspan=\"2\" class=\"even\">"); if ( (certfile = fopen(certfilestr, "r")) != NULL) { PEM_read_X509(certfile, &cert, NULL, NULL); certsubject = X509_get_subject_name(cert); /* display the subject data, use the UTF-8 flag to show * * Japanese Kanji, also needs the separator flag to work */ X509_NAME_print_ex_fp(cgiOut, certsubject, 0, ASN1_STRFLGS_UTF8_CONVERT|XN_FLAG_SEP_CPLUS_SPC); /* store certificate start date for later eval */ start_date = X509_get_notBefore(cert); /* store certificate expiration date for later eval */ expiration_date = X509_get_notAfter(cert); /* check the start and end dates in the cert */ if (X509_cmp_current_time (X509_get_notBefore (cert)) >= 0) /* flag the certificate as not valid yet */ certvalidity = 0; else if (X509_cmp_current_time (X509_get_notAfter (cert)) <= 0) /* flag the certificate as expired */ certvalidity = 0; else /* flag the certificate is still valid */ certvalidity = 1; fclose(certfile); } else fprintf(cgiOut, "Error: Can't open certificate file %s for reading.", certfilestr); fprintf(cgiOut, "</td>\n"); if(certvalidity == 0) { /* expiration bar display column */ fprintf(cgiOut, "<th rowspan=\"2\">\n"); fprintf(cgiOut, "<table class=\"led\">\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, "</table>\n"); fprintf(cgiOut, "</th>\n"); /* remaining days before expiration column */ fprintf(cgiOut, "<th class=\"exnok\" rowspan=\"2\">\n"); fprintf(cgiOut, "Inval<br />Expd"); fprintf(cgiOut, "</th>\n"); } if(certvalidity == 1) { /* ------ START get the certificate lifetime in seconds ------ */ /* copy the start date into a string */ membio = BIO_new(BIO_s_mem()); ASN1_TIME_print(membio, start_date); BIO_gets(membio, membio_buf, sizeof(membio_buf)); BIO_free(membio); /* parse the start date string into a time struct */ memset (&start_tm, '\0', sizeof(start_tm)); strptime(membio_buf, "%h %d %T %Y %z", &start_tm); start = mktime(&start_tm); /* ------ START get the certificate remaining time in seconds ------ */ /* copy the expiration date into a string */ membio = BIO_new(BIO_s_mem()); ASN1_TIME_print(membio, expiration_date); BIO_gets(membio, membio_buf, sizeof(membio_buf)); BIO_free(membio); /* parse the expiration date string into a time struct */ memset (&expiration_tm, '\0', sizeof(expiration_tm)); strptime(membio_buf, "%h %d %T %Y %z", &expiration_tm); /* get the current time */ now = time(NULL); expiration = mktime(&expiration_tm); /* get the time difference between expiration time and current time */ remaining_secs = difftime(expiration, now); /* ------ END get the certificate remaining time in seconds ------ */ /* get the time difference between start and expiration time */ available_secs = difftime(expiration, start); /* ------ END get the certificate lifetime in seconds ------ */ /* ------ START calculate percentage of lifetime left ------ */ /* remaining_secs *100 */ /* ------------------- = X, rounded down with floor() */ /* available_secs */ percent = floor((remaining_secs*100)/available_secs); /* ------ END calculate percentage of lifetime left ------ */ /* expiration bar display column */ fprintf(cgiOut, "<th rowspan=\"2\">\n"); fprintf(cgiOut, "<table class=\"led\">\n"); if (percent >= 90) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=\"#00FF00\"></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 80) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=\"#00FF33\"></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 70) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=\"#99FF33\"></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 60) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=\"#FFFF00\"></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 50) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=\"#FFCC00\"></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 40) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=\"#FF9900\"></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 30) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=\"#FF6600\"></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 20) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=\"#FF3300\"></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); if (percent >= 10) fprintf(cgiOut, " <tr><td class=\"led\" bgcolor=\"#FF0000\"></td></tr>\n"); else fprintf(cgiOut, " <tr><td class=\"led-off\"></td></tr>\n"); fprintf(cgiOut, "</table>\n"); fprintf(cgiOut, "</th>\n"); /* remaining days before expiration column */ //fprintf(cgiOut, membio_buf); if (percent < 10) fprintf(cgiOut, "<th class=\"exnok\" rowspan=\"2\">\n"); else fprintf(cgiOut, "<th class=\"exok\" rowspan=\"2\">\n"); if(floor(remaining_secs/63072000) > 0) fprintf(cgiOut, "%.f<br />years", remaining_secs/31536000); else if(floor(remaining_secs/86400) > 0 ) fprintf(cgiOut, "%.f<br />days", remaining_secs/86400); else if(floor(remaining_secs/3600) > 0 ) fprintf(cgiOut, "%.f<br />hours", remaining_secs/3600); else if(floor(remaining_secs/60) > 0 ) fprintf(cgiOut, "%.f<br />mins", remaining_secs/60); else fprintf(cgiOut, "%.f<br />secs", remaining_secs); fprintf(cgiOut, "</th>\n"); } /* action column */ fprintf(cgiOut, "<th>"); fprintf(cgiOut, "<form action=\"getcert.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"cfilename\" "); fprintf(cgiOut, "value=\"%s\" />\n", certstore_files[tempcounter]->d_name); fprintf(cgiOut, "<input type=\"hidden\" name=\"format\" value=\"text\" />\n"); fprintf(cgiOut, "<input class=\"getcert\" type=\"submit\" value=\"Detail\" />\n"); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th>\n"); fprintf(cgiOut, "<form action=\"certrenew.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"cert-renew\" "); fprintf(cgiOut, "value=\""); PEM_write_bio_X509(outbio, cert); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input class=\"getcert\" type=\"submit\" value=\"Renew\" />\n"); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "</tr>\n"); if(strcmp(sorting, "asc") == 0) tempcounter++; } fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th colspan=\"5\">"); fprintf(cgiOut, "Total # of certs: %d | ", certcounter); fprintf(cgiOut, "Page %d of %d", pagenumber, pagecounter); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "</table>\n"); fprintf(cgiOut, "<p></p>\n"); fprintf(cgiOut, "<table>\n"); fprintf(cgiOut, "<tr>\n"); fprintf(cgiOut, "<th>\n"); fprintf(cgiOut, "<form action=\"certstore.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"sort\" "); fprintf(cgiOut, "value=\"desc\" />\n"); fprintf(cgiOut, "<input type=\"submit\" name=\"sort\""); fprintf(cgiOut, " value=\"Latest Certs first\" />\n"); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "<th>\n"); fprintf(cgiOut, "<form action=\"certstore.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"sort\" "); fprintf(cgiOut, "value=\"asc\" />\n"); fprintf(cgiOut, "<input type=\"submit\" name=\"sort\""); fprintf(cgiOut, " value=\"Oldest Certs first\" />\n"); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); // filler 1 fprintf(cgiOut, "<th width=\"15\">"); fprintf(cgiOut, " "); fprintf(cgiOut, "</th>\n"); // goto page 1 fprintf(cgiOut, "<th width=\"5\">\n"); fprintf(cgiOut, "<form action=\"certstore.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"submit\" value=\"<<\" />\n"); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); // goto page before fprintf(cgiOut, "<th width=\"5\">\n"); fprintf(cgiOut, "<form action=\"certstore.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"certcounter\" "); fprintf(cgiOut, "value=\"%d\" />\n", certcounter); fprintf(cgiOut, "<input type=\"hidden\" name=\"pagecounter\" "); fprintf(cgiOut, "value=\"%d\" />\n", pagecounter); fprintf(cgiOut, "<input type=\"hidden\" name=\"page\" "); fprintf(cgiOut, "value=\""); tempcounter = 0; if(pagenumber > 1) tempcounter = pagenumber - 1; else tempcounter = 1; fprintf(cgiOut, "%d", tempcounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input type=\"submit\" value=\"< 1\" />\n"); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); // goto page after fprintf(cgiOut, "<th width=\"5\">\n"); fprintf(cgiOut, "<form action=\"certstore.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"certcounter\" "); fprintf(cgiOut, "value=\"%d\" />\n", certcounter); fprintf(cgiOut, "<input type=\"hidden\" name=\"pagecounter\" "); fprintf(cgiOut, "value=\"%d\" />\n", pagecounter); fprintf(cgiOut, "<input type=\"hidden\" name=\"page\" "); fprintf(cgiOut, "value=\""); tempcounter = 0; if(pagecounter > pagenumber) tempcounter = pagenumber + 1; else tempcounter = pagecounter; fprintf(cgiOut, "%d", tempcounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input type=\"submit\" value=\"1 >\" />\n"); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); // goto last page fprintf(cgiOut, "<th width=\"5\">\n"); fprintf(cgiOut, "<form action=\"certstore.cgi\" method=\"post\">"); fprintf(cgiOut, "<input type=\"hidden\" name=\"certcounter\" "); fprintf(cgiOut, "value=\"%d\" />\n", certcounter); fprintf(cgiOut, "<input type=\"hidden\" name=\"pagecounter\" "); fprintf(cgiOut, "value=\"%d\" />\n", pagecounter); fprintf(cgiOut, "<input type=\"hidden\" name=\"page\" "); fprintf(cgiOut, "value=\"%d\" />\n", pagecounter); fprintf(cgiOut, "<input type=\"submit\" value=\">>\" />\n"); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); // goto page number fprintf(cgiOut, "<th width=\"120\">\n"); fprintf(cgiOut, "<form class=\"setpage\" action=\"certstore.cgi\" method=\"post\">\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"certcounter\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", certcounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input type=\"hidden\" name=\"pagecounter\" "); fprintf(cgiOut, "value=\""); fprintf(cgiOut, "%d", pagecounter); fprintf(cgiOut, "\" />\n"); fprintf(cgiOut, "<input class=\"goto\" type=\"submit\" value=\"Goto\" />\n"); fprintf(cgiOut, "<input class=\"page\" type=\"text\" name=\"page\" "); fprintf(cgiOut, "value=\"%d\" />\n", pagecounter); fprintf(cgiOut, "</form>\n"); fprintf(cgiOut, "</th>\n"); fprintf(cgiOut, "</tr>\n"); fprintf(cgiOut, "</table>\n"); /* ---------------------------------------------------------------------------* * end the html output * * ---------------------------------------------------------------------------*/ pagefoot(); BIO_free(outbio); return(0); }
getdns_return_t _getdns_verify_pinset_match(const sha256_pin_t *pinset, X509_STORE_CTX *store) { getdns_return_t ret = GETDNS_RETURN_GENERIC_ERROR; X509 *x; int i, len; unsigned char raw[4096]; unsigned char *next = raw; unsigned char buf[sizeof(pinset->pin)]; const sha256_pin_t *p; if (pinset == NULL || store == NULL) return GETDNS_RETURN_GENERIC_ERROR; /* start at the base of the chain (the end-entity cert) and * make sure that some valid element of the chain does match * the pinset. */ /* Testing with OpenSSL 1.0.1e-1 on debian indicates that * store->untrusted holds the chain offered by the server in * the order that the server offers it. If the server offers * bogus certificates (that is, matching and valid certs that * belong to private keys that the server does not control), * the the verification will succeed (including this pinset * check), but the handshake will fail outside of this * verification. */ /* TODO: how do we handle raw public keys? */ for (i = 0; i < sk_X509_num(store->untrusted); i++) { if (i > 0) { /* TODO: how do we ensure that the certificates in * each stage appropriately sign the previous one? * for now, to be safe, we only examine the end-entity * cert: */ return GETDNS_RETURN_GENERIC_ERROR; } x = sk_X509_value(store->untrusted, i); if (x->cert_info == NULL) continue; #if defined(STUB_DEBUG) && STUB_DEBUG DEBUG_STUB("--- %s: name of cert %d:\n", __FUNCTION__, i); if (x->cert_info->subject != NULL) X509_NAME_print_ex_fp(stderr, x->cert_info->subject, 4, XN_FLAG_ONELINE); fprintf(stderr, "\n"); #endif if (x->cert_info->key == NULL) continue; /* digest the cert with sha256 */ len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), NULL); if (len > sizeof(raw)) { DEBUG_STUB("--- %s: pubkey %d is larger than %ld octets\n", __FUNCTION__, i, sizeof(raw)); continue; } i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &next); if (next - raw != len) { DEBUG_STUB("--- %s: pubkey %d claimed it needed %d octets, really needed %ld\n", __FUNCTION__, i, len, next - raw); continue; } SHA256(raw, len, buf); /* compare it */ for (p = pinset; p; p = p->next) if (0 == memcmp(buf, p->pin, sizeof(p->pin))) { DEBUG_STUB("--- %s: pubkey %d matched pin %p (%ld)!\n", __FUNCTION__, i, p, sizeof(p->pin)); return GETDNS_RETURN_GOOD; } else DEBUG_STUB("--- %s: pubkey %d did not match pin %p!\n", __FUNCTION__, i, p); } return ret; }