static GTlsCertificateFlags double_check_before_after_dates (GTlsCertificateOpenssl *chain) { GTlsCertificateFlags gtls_flags = 0; X509 *cert; while (chain) { ASN1_TIME *not_before; ASN1_TIME *not_after; cert = g_tls_certificate_openssl_get_cert (chain); not_before = X509_get_notBefore (cert); not_after = X509_get_notAfter (cert); if (X509_cmp_current_time (not_before) > 0) gtls_flags |= G_TLS_CERTIFICATE_NOT_ACTIVATED; if (X509_cmp_current_time (not_after) < 0) gtls_flags |= G_TLS_CERTIFICATE_EXPIRED; chain = G_TLS_CERTIFICATE_OPENSSL (g_tls_certificate_get_issuer (G_TLS_CERTIFICATE (chain))); } return gtls_flags; }
/** * check_certificate_expiration - Check if a certificate has expired * @param peercert Certificate to check * @param silent If true, don't notify the user if the certificate has expired * @retval true Certificate is valid * @retval false Certificate has expired (or hasn't yet become valid) */ static bool check_certificate_expiration(X509 *peercert, bool silent) { if (C_SslVerifyDates == MUTT_NO) return true; if (X509_cmp_current_time(X509_get0_notBefore(peercert)) >= 0) { if (!silent) { mutt_debug(LL_DEBUG2, "Server certificate is not yet valid\n"); mutt_error(_("Server certificate is not yet valid")); } return false; } if (X509_cmp_current_time(X509_get0_notAfter(peercert)) <= 0) { if (!silent) { mutt_debug(LL_DEBUG2, "Server certificate has expired\n"); mutt_error(_("Server certificate has expired")); } return false; } return true; }
bool digidoc::X509Cert::isValid() const throw(IOException) { int notBefore = X509_cmp_current_time(cert->cert_info->validity->notBefore); int notAfter = X509_cmp_current_time(cert->cert_info->validity->notAfter); if(notBefore == 0 || notAfter == 0) THROW_IOEXCEPTION("Failed to validate cert",ERR_reason_error_string(ERR_get_error())); return notBefore < 0 && notAfter > 0; }
bool bdoc::X509Cert::isValid() const { int notBefore = X509_cmp_current_time(cert->cert_info->validity->notBefore); int notAfter = X509_cmp_current_time(cert->cert_info->validity->notAfter); if (notBefore == 0 || notAfter == 0) { THROW_STACK_EXCEPTION("Failed to validate cert", ERR_reason_error_string(ERR_get_error())); } return notBefore < 0 && notAfter > 0; }
static int check_certificate_by_digest (X509 *peercert) { unsigned char peermd[EVP_MAX_MD_SIZE]; unsigned int peermdlen; X509 *cert = NULL; int pass = 0; FILE *fp; /* expiration check */ if (option (OPTSSLVERIFYDATES) != M_NO) { if (X509_cmp_current_time (X509_get_notBefore (peercert)) >= 0) { dprint (2, (debugfile, "Server certificate is not yet valid\n")); mutt_error (_("Server certificate is not yet valid")); mutt_sleep (2); return 0; } if (X509_cmp_current_time (X509_get_notAfter (peercert)) <= 0) { dprint (2, (debugfile, "Server certificate has expired")); mutt_error (_("Server certificate has expired")); mutt_sleep (2); return 0; } } if ((fp = fopen (SslCertFile, "rt")) == NULL) return 0; if (!X509_digest (peercert, EVP_sha1(), peermd, &peermdlen)) { safe_fclose (&fp); return 0; } while ((cert = READ_X509_KEY (fp, &cert)) != NULL) { pass = compare_certificates (cert, peercert, peermd, peermdlen) ? 0 : 1; if (pass) break; } X509_free (cert); safe_fclose (&fp); return pass; }
/* * Check if a CRL entry is expired. */ static int crl_entry_expired(X509_CRL *crl) { int lastUpdate, nextUpdate; if (!crl) { return 0; } lastUpdate = X509_cmp_current_time(X509_CRL_get_lastUpdate(crl)); nextUpdate = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); if (lastUpdate < 0 && nextUpdate > 0) { return 0; } return 1; }
bool SSLConnection::checkCertDigest() { unsigned char peermd[EVP_MAX_MD_SIZE]; unsigned int peermdlen; X509 *c = NULL; bool pass = false; FILE *fp; buffer_t msg; buffer_init(&msg); /* expiration check */ if (X509_cmp_current_time (X509_get_notBefore (cert)) >= 0) { buffer_shrink(&msg,0); buffer_add_str(&msg,_("Server certificate is not yet valid."),-1); displayError.emit(&msg); buffer_free(&msg); return 0; } if (X509_cmp_current_time (X509_get_notAfter (cert)) <= 0) { buffer_shrink(&msg,0); buffer_add_str(&msg,_("Server certificate has expired."),-1); displayError.emit(&msg); buffer_free(&msg); return 0; } buffer_free(&msg); if ((fp = fopen (SSLCertFile, "rt")) == NULL) return false; if (!X509_digest (cert, EVP_sha1 (), peermd, &peermdlen)) { fclose (fp); return false; } while ((c = READ_X509_KEY (fp, &c)) != NULL) { pass = X509_cmp (c, peermd, peermdlen); if (pass) break; } X509_free(c); fclose (fp); return pass; }
/** * ssl_load_certificates - Load certificates and filter out the expired ones * @param ctx SSL context * @retval 1 Success * @retval 0 Error * * ssl certificate verification can behave strangely if there are expired certs * loaded into the trusted store. This function filters out expired certs. * * Previously the code used this form: * SSL_CTX_load_verify_locations (ssldata->ctx, #C_CertificateFile, NULL); */ static int ssl_load_certificates(SSL_CTX *ctx) { FILE *fp = NULL; X509 *cert = NULL; X509_STORE *store = NULL; int rc = 1; char buf[256]; mutt_debug(LL_DEBUG2, "loading trusted certificates\n"); store = SSL_CTX_get_cert_store(ctx); if (!store) { store = X509_STORE_new(); SSL_CTX_set_cert_store(ctx, store); } fp = fopen(C_CertificateFile, "rt"); if (!fp) return 0; while (NULL != PEM_read_X509(fp, &cert, NULL, NULL)) { if ((X509_cmp_current_time(X509_get0_notBefore(cert)) >= 0) || (X509_cmp_current_time(X509_get0_notAfter(cert)) <= 0)) { mutt_debug(LL_DEBUG2, "filtering expired cert: %s\n", X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf))); } else { X509_STORE_add_cert(store, cert); } } /* PEM_read_X509 sets the error NO_START_LINE on eof */ if (ERR_GET_REASON(ERR_peek_last_error()) != PEM_R_NO_START_LINE) rc = 0; ERR_clear_error(); X509_free(cert); mutt_file_fclose(&fp); return rc; }
static int interactive_check_cert (X509 *cert, int idx, int len) { static const char * const part[] = {"/CN=", "/Email=", "/O=", "/OU=", "/L=", "/ST=", "/C="}; char helpstr[LONG_STRING]; char buf[STRING]; char title[STRING]; MUTTMENU *menu = mutt_new_menu (-1); int done, row, i; FILE *fp; char *name = NULL, *c; dprint (2, (debugfile, "interactive_check_cert: %s\n", cert->name)); menu->max = 19; menu->dialog = (char **) safe_calloc (1, menu->max * sizeof (char *)); for (i = 0; i < menu->max; i++) menu->dialog[i] = (char *) safe_calloc (1, SHORT_STRING * sizeof (char)); row = 0; strfcpy (menu->dialog[row], _("This certificate belongs to:"), SHORT_STRING); row++; name = X509_NAME_oneline (X509_get_subject_name (cert), buf, sizeof (buf)); dprint (2, (debugfile, "oneline: %s\n", name)); for (i = 0; i < 5; i++) { c = x509_get_part (name, part[i]); snprintf (menu->dialog[row++], SHORT_STRING, " %s", c); } row++; strfcpy (menu->dialog[row], _("This certificate was issued by:"), SHORT_STRING); row++; name = X509_NAME_oneline (X509_get_issuer_name (cert), buf, sizeof (buf)); for (i = 0; i < 5; i++) { c = x509_get_part (name, part[i]); snprintf (menu->dialog[row++], SHORT_STRING, " %s", c); } row++; snprintf (menu->dialog[row++], SHORT_STRING, _("This certificate is valid")); snprintf (menu->dialog[row++], SHORT_STRING, _(" from %s"), asn1time_to_string (X509_get_notBefore (cert))); snprintf (menu->dialog[row++], SHORT_STRING, _(" to %s"), asn1time_to_string (X509_get_notAfter (cert))); row++; buf[0] = '\0'; x509_fingerprint (buf, sizeof (buf), cert); snprintf (menu->dialog[row++], SHORT_STRING, _("Fingerprint: %s"), buf); snprintf (title, sizeof (title), _("SSL Certificate check (certificate %d of %d in chain)"), len - idx, len); menu->title = title; if (SslCertFile && (option (OPTSSLVERIFYDATES) == M_NO || (X509_cmp_current_time (X509_get_notAfter (cert)) >= 0 && X509_cmp_current_time (X509_get_notBefore (cert)) < 0))) { menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always"); menu->keys = _("roa"); } else { menu->prompt = _("(r)eject, accept (o)nce"); menu->keys = _("ro"); } helpstr[0] = '\0'; mutt_make_help (buf, sizeof (buf), _("Exit "), MENU_GENERIC, OP_EXIT); safe_strcat (helpstr, sizeof (helpstr), buf); mutt_make_help (buf, sizeof (buf), _("Help"), MENU_GENERIC, OP_HELP); safe_strcat (helpstr, sizeof (helpstr), buf); menu->help = helpstr; done = 0; set_option(OPTUNBUFFEREDINPUT); while (!done) { switch (mutt_menuLoop (menu)) { case -1: /* abort */ case OP_MAX + 1: /* reject */ case OP_EXIT: done = 1; break; case OP_MAX + 3: /* accept always */ done = 0; if ((fp = fopen (SslCertFile, "a"))) { if (PEM_write_X509 (fp, cert)) done = 1; safe_fclose (&fp); } if (!done) { mutt_error (_("Warning: Couldn't save certificate")); mutt_sleep (2); } else { mutt_message (_("Certificate saved")); mutt_sleep (0); } /* fall through */ case OP_MAX + 2: /* accept once */ done = 2; ssl_cache_trusted_cert (cert); break; } } unset_option(OPTUNBUFFEREDINPUT); mutt_menuDestroy (&menu); dprint (2, (debugfile, "ssl interactive_check_cert: done=%d\n", done)); return (done == 2); }
static int validate_server_certificate(int cert_valid, X509_STORE_CTX *store_ctx) { SSL *ssl; serf_ssl_context_t *ctx; X509 *server_cert; int err, depth; int failures = 0; ssl = X509_STORE_CTX_get_ex_data(store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); ctx = SSL_get_app_data(ssl); server_cert = X509_STORE_CTX_get_current_cert(store_ctx); depth = X509_STORE_CTX_get_error_depth(store_ctx); /* If the certification was found invalid, get the error and convert it to something our caller will understand. */ if (! cert_valid) { err = X509_STORE_CTX_get_error(store_ctx); switch(err) { case X509_V_ERR_CERT_NOT_YET_VALID: failures |= SERF_SSL_CERT_NOTYETVALID; break; case X509_V_ERR_CERT_HAS_EXPIRED: failures |= SERF_SSL_CERT_EXPIRED; break; case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: failures |= SERF_SSL_CERT_SELF_SIGNED; break; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: failures |= SERF_SSL_CERT_UNKNOWNCA; break; default: failures |= SERF_SSL_CERT_UNKNOWN_FAILURE; break; } } /* Check certificate expiry dates. */ if (X509_cmp_current_time(X509_get_notBefore(server_cert)) >= 0) { failures |= SERF_SSL_CERT_NOTYETVALID; } else if (X509_cmp_current_time(X509_get_notAfter(server_cert)) <= 0) { failures |= SERF_SSL_CERT_EXPIRED; } if (ctx->server_cert_callback && (depth == 0 || failures)) { apr_status_t status; serf_ssl_certificate_t *cert; apr_pool_t *subpool; apr_pool_create(&subpool, ctx->pool); cert = apr_palloc(subpool, sizeof(serf_ssl_certificate_t)); cert->ssl_cert = server_cert; cert->depth = depth; /* Callback for further verification. */ status = ctx->server_cert_callback(ctx->server_cert_userdata, failures, cert); if (status == APR_SUCCESS) cert_valid = 1; else /* Pass the error back to the caller through the context-run. */ ctx->pending_err = status; apr_pool_destroy(subpool); } return cert_valid; }
GBytes *cms_sign(GBytes *content, const gchar *certfile, const gchar *keyfile, gchar **interfiles, GError **error) { GError *ierror = NULL; BIO *incontent = BIO_new_mem_buf((void *)g_bytes_get_data(content, NULL), g_bytes_get_size(content)); BIO *outsig = BIO_new(BIO_s_mem()); X509 *signcert = NULL; EVP_PKEY *pkey = NULL; STACK_OF(X509) *intercerts = NULL; CMS_ContentInfo *cms = NULL; GBytes *res = NULL; int flags = CMS_DETACHED | CMS_BINARY; g_return_val_if_fail(content != NULL, NULL); g_return_val_if_fail(certfile != NULL, NULL); g_return_val_if_fail(keyfile != NULL, NULL); g_return_val_if_fail(error == NULL || *error == NULL, NULL); signcert = load_cert(certfile, &ierror); if (signcert == NULL) { g_propagate_error(error, ierror); goto out; } pkey = load_key(keyfile, &ierror); if (pkey == NULL) { g_propagate_error(error, ierror); goto out; } intercerts = sk_X509_new_null(); for (gchar **intercertpath = interfiles; intercertpath && *intercertpath != NULL; intercertpath++) { X509 *intercert = load_cert(*intercertpath, &ierror); if (intercert == NULL) { g_propagate_error(error, ierror); goto out; } sk_X509_push(intercerts, intercert); } cms = CMS_sign(signcert, pkey, intercerts, incontent, flags); if (cms == NULL) { unsigned long err; const gchar *data; int errflags; err = ERR_get_error_line_data(NULL, NULL, &data, &errflags); g_set_error( error, R_SIGNATURE_ERROR, R_SIGNATURE_ERROR_INVALID, "failed to create signature: %s", (errflags & ERR_TXT_STRING) ? data : ERR_error_string(err, NULL)); goto out; } if (!i2d_CMS_bio(outsig, cms)) { g_set_error_literal( error, R_SIGNATURE_ERROR, R_SIGNATURE_ERROR_SERIALIZE_SIG, "failed to serialize signature"); goto out; } res = bytes_from_bio(outsig); if (!res) { g_set_error_literal( error, R_SIGNATURE_ERROR, R_SIGNATURE_ERROR_UNKNOWN, "Read zero bytes"); goto out; } /* keyring was given, perform verification to obtain trust chain */ if (r_context()->config->keyring_path) { g_autoptr(CMS_ContentInfo) vcms = NULL; g_autoptr(X509_STORE) store = NULL; STACK_OF(X509) *verified_chain = NULL; g_message("Keyring given, doing signature verification"); if (!cms_verify(content, res, &vcms, &store, &ierror)) { g_propagate_error(error, ierror); res = NULL; goto out; } if (!cms_get_cert_chain(vcms, store, &verified_chain, &ierror)) { g_propagate_error(error, ierror); res = NULL; goto out; } for (int i = 0; i < sk_X509_num(verified_chain); i++) { const ASN1_TIME *expiry_time; struct tm *next_month; time_t now; time_t comp; time(&now); next_month = gmtime(&now); next_month->tm_mon += 1; if (next_month->tm_mon == 12) next_month->tm_mon = 0; comp = timegm(next_month); expiry_time = X509_get0_notAfter(sk_X509_value(verified_chain, i)); /* Check if expiry time is within last month */ if (X509_cmp_current_time(expiry_time) == 1 && X509_cmp_time(expiry_time, &comp) == -1) { char buf[BUFSIZ]; X509_NAME_oneline(X509_get_subject_name(sk_X509_value(verified_chain, i)), buf, sizeof buf); g_warning("Certificate %d (%s) will exipre in less than a month!", i + 1, buf); } } sk_X509_pop_free(verified_chain, X509_free); } else { g_message("No keyring given, skipping signature verification"); } out: ERR_print_errors_fp(stdout); BIO_free_all(incontent); BIO_free_all(outsig); return res; }
/* based on BSD-style licensed code of mod_ssl */ static int crl_check(CLI *c, X509_STORE_CTX *callback_ctx) { X509_STORE_CTX store_ctx; X509_OBJECT obj; X509_NAME *subject; X509_NAME *issuer; X509 *cert; X509_CRL *crl; X509_REVOKED *revoked; EVP_PKEY *pubkey; long serial; int i, n, rc; char *cp; ASN1_TIME *last_update=NULL, *next_update=NULL; /* determine certificate ingredients in advance */ cert=X509_STORE_CTX_get_current_cert(callback_ctx); subject=X509_get_subject_name(cert); issuer=X509_get_issuer_name(cert); /* try to retrieve a CRL corresponding to the _subject_ of * the current certificate in order to verify it's integrity */ memset((char *)&obj, 0, sizeof obj); X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL); rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj); X509_STORE_CTX_cleanup(&store_ctx); crl=obj.data.crl; if(rc>0 && crl) { cp=X509_NAME_oneline(subject, NULL, 0); s_log(LOG_INFO, "CRL: issuer: %s", cp); OPENSSL_free(cp); last_update=X509_CRL_get_lastUpdate(crl); next_update=X509_CRL_get_nextUpdate(crl); log_time(LOG_INFO, "CRL: last update", last_update); log_time(LOG_INFO, "CRL: next update", next_update); /* verify the signature on this CRL */ pubkey=X509_get_pubkey(cert); if(X509_CRL_verify(crl, pubkey)<=0) { s_log(LOG_WARNING, "CRL: Invalid signature"); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); X509_OBJECT_free_contents(&obj); if(pubkey) EVP_PKEY_free(pubkey); return 0; /* reject connection */ } if(pubkey) EVP_PKEY_free(pubkey); /* check date of CRL to make sure it's not expired */ if(!next_update) { s_log(LOG_WARNING, "CRL: Invalid nextUpdate field"); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); X509_OBJECT_free_contents(&obj); return 0; /* reject connection */ } if(X509_cmp_current_time(next_update)<0) { s_log(LOG_WARNING, "CRL: CRL Expired - revoking all certificates"); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_HAS_EXPIRED); X509_OBJECT_free_contents(&obj); return 0; /* reject connection */ } X509_OBJECT_free_contents(&obj); } /* try to retrieve a CRL corresponding to the _issuer_ of * the current certificate in order to check for revocation */ memset((char *)&obj, 0, sizeof obj); X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL); rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj); X509_STORE_CTX_cleanup(&store_ctx); crl=obj.data.crl; if(rc>0 && crl) { /* check if the current certificate is revoked by this CRL */ n=sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); for(i=0; i<n; i++) { revoked=sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); if(ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(cert)) == 0) { serial=ASN1_INTEGER_get(revoked->serialNumber); cp=X509_NAME_oneline(issuer, NULL, 0); s_log(LOG_WARNING, "CRL: Certificate with serial %ld (0x%lX) " "revoked per CRL from issuer %s", serial, serial, cp); OPENSSL_free(cp); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REVOKED); X509_OBJECT_free_contents(&obj); return 0; /* reject connection */ } } X509_OBJECT_free_contents(&obj); } return 1; /* accept connection */ }
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); }
DWORD VMCADecodeCert( PSTR pszCertificate, PVMCA_DB_CERTIFICATE_ENTRY* ppEntry ) { DWORD dwError = 0; PVMCA_DB_CERTIFICATE_ENTRY pDBEntry = NULL; PSTR pszCertName = NULL; PSTR pszCertSerial = NULL; PSTR pszNotBefore = NULL; PSTR pszNotAfter = NULL; PSTR pszIssuerName = NULL; X509 *pCert = NULL; if (pszCertificate == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } if (ppEntry == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAAllocateMemory( sizeof(VMCA_DB_CERTIFICATE_ENTRY), (PVOID*) &pDBEntry); BAIL_ON_VMCA_ERROR(dwError); memset(pDBEntry,0, sizeof(VMCA_DB_CERTIFICATE_ENTRY)); VMCAAllocateStringA(pszCertificate, (PSTR*)&pDBEntry->pCertBlob); //pDBEntry->pCertBlob = (PBYTE) pszCertificate; pDBEntry->dwCertSize = (DWORD)strlen(pszCertificate); dwError = VMCAPEMToX509(pszCertificate, &pCert); BAIL_ON_VMCA_ERROR(dwError); if (X509_cmp_current_time(X509_get_notAfter(pCert)) < 0) { pDBEntry->dwRevoked = VMCA_CERTIFICATE_EXPIRED; } dwError = VMCAGetCertificateName(pCert, &pszCertName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszCertName, &pDBEntry->pwszCommonName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetCertificateSerial(pCert, &pszCertSerial); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszCertSerial, &pDBEntry->pwszSerial); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetIssuerName(pCert, &pszIssuerName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszIssuerName, &pDBEntry->pwszIssuerName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetCertificateTime(pCert, &pszNotBefore, &pszNotAfter); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszNotBefore, &pDBEntry->pwszTimeValidFrom); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszNotBefore, &pDBEntry->pwszTimeValidTo); BAIL_ON_VMCA_ERROR(dwError); *ppEntry = pDBEntry; cleanup: if(pCert) { X509_free(pCert); } VMCA_SAFE_FREE_STRINGA(pszCertName); VMCA_SAFE_FREE_STRINGA(pszCertSerial); VMCA_SAFE_FREE_STRINGA(pszNotBefore); VMCA_SAFE_FREE_STRINGA(pszNotAfter); VMCA_SAFE_FREE_STRINGA(pszIssuerName); return dwError; error : VMCAFreeDBEntryFields(pDBEntry); goto cleanup; }
static int __pkcs11h_crypto_openssl_certificate_get_expiration ( IN void * const global_data, IN const unsigned char * const blob, IN const size_t blob_size, OUT time_t * const expiration ) { X509 *x509 = NULL; __pkcs11_openssl_d2i_t d2i; const ASN1_TIME *notBefore; const ASN1_TIME *notAfter; (void)global_data; /*_PKCS11H_ASSERT (global_data!=NULL); NOT NEEDED*/ _PKCS11H_ASSERT (blob!=NULL); _PKCS11H_ASSERT (expiration!=NULL); *expiration = (time_t)0; if ((x509 = X509_new ()) == NULL) { goto cleanup; } d2i = (__pkcs11_openssl_d2i_t)blob; if (!d2i_X509 (&x509, &d2i, blob_size)) { goto cleanup; } notBefore = X509_get0_notBefore (x509); notAfter = X509_get0_notAfter (x509); if ( notBefore != NULL && notAfter != NULL && X509_cmp_current_time (notBefore) <= 0 && X509_cmp_current_time (notAfter) >= 0 && notAfter->length >= 12 ) { struct tm tm1; memset (&tm1, 0, sizeof (tm1)); tm1.tm_year = (notAfter->data[ 0] - '0') * 10 + (notAfter->data[ 1] - '0') + 100; tm1.tm_mon = (notAfter->data[ 2] - '0') * 10 + (notAfter->data[ 3] - '0') - 1; tm1.tm_mday = (notAfter->data[ 4] - '0') * 10 + (notAfter->data[ 5] - '0'); tm1.tm_hour = (notAfter->data[ 6] - '0') * 10 + (notAfter->data[ 7] - '0'); tm1.tm_min = (notAfter->data[ 8] - '0') * 10 + (notAfter->data[ 9] - '0'); tm1.tm_sec = (notAfter->data[10] - '0') * 10 + (notAfter->data[11] - '0'); *expiration = mktime (&tm1); *expiration += (int)(mktime (localtime (expiration)) - mktime (gmtime (expiration))); } cleanup: if (x509 != NULL) { X509_free (x509); x509 = NULL; } return *expiration != (time_t)0; }
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); }
/* based on the code of stunnel utility */ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { X509_STORE* store; X509_STORE_CTX store_ctx; X509_OBJECT obj; X509_NAME* subject; X509_NAME* issuer; X509* cert; X509_CRL* crl; X509_REVOKED* revoked; EVP_PKEY* pubkey; int i, n, rc; ASN1_TIME* next_update = NULL; if (!preverify_ok) { return 0; } if ((store = pthread_getspecific(tls_store_key)) == NULL) { ERROR("Failed to get thread-specific X509 store"); return 1; /* fail */ } cert = X509_STORE_CTX_get_current_cert(x509_ctx); subject = X509_get_subject_name(cert); issuer = X509_get_issuer_name(cert); /* try to retrieve a CRL corresponding to the _subject_ of * the current certificate in order to verify it's integrity */ memset((char *)&obj, 0, sizeof obj); X509_STORE_CTX_init(&store_ctx, store, NULL, NULL); rc = X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj); X509_STORE_CTX_cleanup(&store_ctx); crl = obj.data.crl; if (rc > 0 && crl) { next_update = X509_CRL_get_nextUpdate(crl); /* verify the signature on this CRL */ pubkey = X509_get_pubkey(cert); if (X509_CRL_verify(crl, pubkey) <= 0) { X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); X509_OBJECT_free_contents(&obj); if (pubkey) { EVP_PKEY_free(pubkey); } return 0; /* fail */ } if (pubkey) { EVP_PKEY_free(pubkey); } /* check date of CRL to make sure it's not expired */ if (!next_update) { X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); X509_OBJECT_free_contents(&obj); return 0; /* fail */ } if (X509_cmp_current_time(next_update) < 0) { X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CRL_HAS_EXPIRED); X509_OBJECT_free_contents(&obj); return 0; /* fail */ } X509_OBJECT_free_contents(&obj); } /* try to retrieve a CRL corresponding to the _issuer_ of * the current certificate in order to check for revocation */ memset((char *)&obj, 0, sizeof obj); X509_STORE_CTX_init(&store_ctx, store, NULL, NULL); rc = X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj); X509_STORE_CTX_cleanup(&store_ctx); crl = obj.data.crl; if (rc > 0 && crl) { /* check if the current certificate is revoked by this CRL */ n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); for (i = 0; i < n; i++) { revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(cert)) == 0) { ERROR("Certificate revoked"); X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CERT_REVOKED); X509_OBJECT_free_contents(&obj); return 0; /* fail */ } } X509_OBJECT_free_contents(&obj); } return 1; /* success */ }
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_REC *server) { GIOSSLChannel *chan; GIOChannel *gchan; int fd; SSL *ssl; SSL_CTX *ctx = NULL; const char *mycert = server->connrec->tls_cert; const char *mypkey = server->connrec->tls_pkey; const char *mypass = server->connrec->tls_pass; const char *cafile = server->connrec->tls_cafile; const char *capath = server->connrec->tls_capath; const char *ciphers = server->connrec->tls_ciphers; gboolean verify = server->connrec->tls_verify; g_return_val_if_fail(handle != NULL, NULL); if(!ssl_inited && !irssi_ssl_init()) return NULL; if(!(fd = g_io_channel_unix_get_fd(handle))) return NULL; ERR_clear_error(); ctx = SSL_CTX_new(SSLv23_client_method()); if (ctx == NULL) { g_error("Could not allocate memory for SSL context"); return NULL; } SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); SSL_CTX_set_default_passwd_cb(ctx, get_pem_password_callback); SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)mypass); if (ciphers != NULL && ciphers[0] != '\0') { if (SSL_CTX_set_cipher_list(ctx, ciphers) != 1) g_warning("No valid SSL cipher suite could be selected"); } if (mycert && *mycert) { char *scert = NULL, *spkey = NULL; FILE *fp; scert = convert_home(mycert); if (mypkey && *mypkey) spkey = convert_home(mypkey); if ((fp = fopen(scert, "r"))) { X509 *cert; /* Let's parse the certificate by hand instead of using * SSL_CTX_use_certificate_file so that we can validate * some parts of it. */ cert = PEM_read_X509(fp, NULL, get_pem_password_callback, (void *)mypass); if (cert != NULL) { /* Only the expiration date is checked right now */ if (X509_cmp_current_time(X509_get_notAfter(cert)) <= 0 || X509_cmp_current_time(X509_get_notBefore(cert)) >= 0) g_warning("The client certificate is expired"); ERR_clear_error(); if (! SSL_CTX_use_certificate(ctx, cert)) g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error())); else if (! SSL_CTX_use_PrivateKey_file(ctx, spkey ? spkey : scert, SSL_FILETYPE_PEM)) g_warning("Loading of private key '%s' failed: %s", mypkey ? mypkey : mycert, ERR_reason_error_string(ERR_get_error())); else if (! SSL_CTX_check_private_key(ctx)) g_warning("Private key does not match the certificate"); X509_free(cert); } else g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error())); fclose(fp); } else g_warning("Could not find client certificate '%s'", scert); g_free(scert); g_free(spkey); } if ((cafile && *cafile) || (capath && *capath)) { char *scafile = NULL; char *scapath = NULL; if (cafile && *cafile) scafile = convert_home(cafile); if (capath && *capath) scapath = convert_home(capath); if (! SSL_CTX_load_verify_locations(ctx, scafile, scapath)) { g_warning("Could not load CA list for verifying TLS server certificate"); g_free(scafile); g_free(scapath); SSL_CTX_free(ctx); return NULL; } g_free(scafile); g_free(scapath); verify = TRUE; } else if (store != NULL) { /* Make sure to increment the refcount every time the store is * used, that's essential not to get it free'd by OpenSSL when * the SSL_CTX is destroyed. */ X509_STORE_up_ref(store); SSL_CTX_set_cert_store(ctx, store); } if(!(ssl = SSL_new(ctx))) { g_warning("Failed to allocate SSL structure"); SSL_CTX_free(ctx); return NULL; } if(!SSL_set_fd(ssl, fd)) { g_warning("Failed to associate socket to SSL stream"); SSL_free(ssl); SSL_CTX_free(ctx); return NULL; } #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME SSL_set_tlsext_host_name(ssl, server->connrec->address); #endif SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); chan = g_new0(GIOSSLChannel, 1); chan->fd = fd; chan->giochan = handle; chan->ssl = ssl; chan->ctx = ctx; chan->server = server; chan->port = port; chan->verify = verify; gchan = (GIOChannel *)chan; gchan->funcs = &irssi_ssl_channel_funcs; g_io_channel_init(gchan); gchan->is_readable = gchan->is_writeable = TRUE; gchan->use_buffer = FALSE; return gchan; }