static gboolean sscg_make_dummy_cert (const gchar *key_file, const gchar *cert_file, const gchar *ca_file, GError **error) { gboolean ret = FALSE; gint exit_status; gchar *stderr_str = NULL; gchar *command_line = NULL; gchar *cn = get_common_name (); gchar *machine_id = get_machine_id (); gchar *org; if (machine_id) org = machine_id; else org = ""; const gchar *argv[] = { "sscg", "--quiet", "--lifetime", "3650", "--key-strength", "2048", "--cert-key-file", key_file, "--cert-file", cert_file, "--ca-file", ca_file, "--hostname", cn, "--organization", org, "--subject-alt-name", "localhost", "--subject-alt-name", "IP:127.0.0.1/255.255.255.255", NULL }; command_line = g_strjoinv (" ", (gchar **)argv); g_info ("Generating temporary certificate using: %s", command_line); if (!g_spawn_sync (NULL, (gchar **)argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &stderr_str, &exit_status, error) || !g_spawn_check_exit_status (exit_status, error)) { /* Failure of SSCG is non-fatal */ g_info ("Error generating temporary dummy cert using sscg, " "falling back to openssl"); g_clear_error (error); goto out; } ret = TRUE; out: g_free (stderr_str); g_free (command_line); g_free (machine_id); g_free (cn); return ret; }
/* * This function reads a common name from a certificate using get_common_name. * It returns ther name or NULL in case of error. Errno is set appropriately. * The file pointer must be opened before calling the function. * The function does not close it. * It allocates my_mail. */ char* read_common_name(FILE* fp){ X509* cert; if(fp==NULL){ return NULL; } if((cert=PEM_read_X509(fp, NULL, NULL, NULL))==NULL){ return NULL; } X509_NAME* name; int ret; char* identifier; char* my_mail = (char*)calloc(1,DIM_MAIL); name = X509_get_subject_name(cert); identifier = X509_NAME_oneline(name, NULL, 0); if((ret=get_common_name(my_mail,identifier)) < 0){ return NULL; } return my_mail; }
/* Check whether the certificate in filename 'filename' has expired; * issue a warning message if 'quiet' is zero. If quiet is non-zero, * returns one to indicate that a warning would have been issued, zero * to indicate no warning would be issued, or -1 if an error * occurred. */ static int check_cert(const char *filename, int quiet) { X509 *cert; FILE *fp; ASN1_UTCTIME *notAfter, *notBefore; time_t begin, end, now; char cname[128]; /* parse the cert */ if ((fp = fopen(filename, "r")) == NULL) return -1; cert = PEM_read_X509(fp, NULL, NULL, NULL); fclose(fp); if (cert == NULL) return -1; /* determine the validity period of the cert. */ notAfter = X509_get_notAfter(cert); notBefore = X509_get_notBefore(cert); /* get time_t's out of X509 times */ begin = decode_utctime(notBefore); end = decode_utctime(notAfter); now = time(NULL); if (end == -1 || begin == -1 || now == -1) return -1; /* find the subject's commonName attribute */ if (get_common_name(cert, cname, sizeof cname)) return -1; X509_free(cert); /* don't warn about the automatically generate certificate */ if (strcmp(cname, "localhost") == 0 || strcmp(cname, "localhost.localdomain") == 0) return -1; return warning(stdout, filename, cname, begin, end, now, quiet); }
static gchar * generate_subject (void) { gchar *cn; gchar *machine_id; gchar *subject; /* * HACK: We have to use a unique value in DN because otherwise * firefox hangs. * * https://bugzilla.redhat.com/show_bug.cgi?id=1204670 * * In addition we have to generate the certificate with CA:TRUE * because old versions of NSS refuse to process self-signed * certificates if that's not the case. * */ cn = get_common_name (); machine_id = get_machine_id (); if (machine_id && !g_str_equal (machine_id, "")) { subject = g_strdup_printf ("/O=%s/CN=%s", machine_id, cn); } else { subject = g_strdup_printf ("/CN=%s", cn); } g_free (cn); g_free (machine_id); return subject; }