/* * Loads authority certificates */ void load_authcerts(const char *type, const char *path, u_char auth_flags) { struct dirent **filelist; char buf[ASN1_BUF_LEN]; char *save_dir; int n; /* change directory to specified path */ save_dir = getcwd(buf, ASN1_BUF_LEN); if (chdir(path)) { openswan_log("Could not change to directory '%s': %s", path, strerror(errno)); } else { DBG(DBG_CONTROL, DBG_log("Changed path to directory '%s'", path)); n = scandir(".", &filelist, (void *) file_select, alphasort); if (n < 0){ char buff[256]; strerror_r(errno, buff, 256 ); openswan_log(" scandir() ./ error: %s", buff); } else { while (n--) { cert_t cert; if (load_cert(CERT_NONE, filelist[n]->d_name, #ifdef SINGLE_CONF_DIR FALSE, /* too verbose in single conf dir */ #else TRUE, #endif type, &cert)) add_authcert(cert.u.x509, auth_flags); free(filelist[n]); } free(filelist); } /* restore directory path */ if(chdir(save_dir) != 0) { char buff[256]; strerror_r(errno, buff, 256 ); openswan_log(" chdir() ./ error: %s", buff); } } }
/* * stores a chained list of end certs and CA certs * * @verified_ca is a copied list of the verified authcerts that have * been placed in the global authcert chain */ void store_x509certs(x509cert_t **firstcert, x509cert_t **verified_ca, bool strict) { x509cert_t *cacerts = NULL; x509cert_t **pp = firstcert; /* first extract CA certs, discarding root CA certs */ while (*pp != NULL) { x509cert_t *cert = *pp; if (cert->isCA) { *pp = cert->next; /* we don't accept self-signed CA certs */ if (same_dn(cert->issuer, cert->subject)) { libreswan_log("self-signed cacert rejected"); free_x509cert(cert); } else { /* insertion into temporary chain of candidate CA certs */ cert->next = cacerts; cacerts = cert; } } else { pp = &cert->next; } } /* now verify the candidate CA certs */ x509cert_t *ver = NULL; while (cacerts != NULL) { realtime_t valid_until; x509cert_t *cert = cacerts; cacerts = cacerts->next; if (trust_authcert_candidate(cert, cacerts) && verify_x509cert(cert, strict, &valid_until, cacerts)) { add_authcert(cert, AUTH_CA); if (ver == NULL) { ver = clone_thing(*cert, "x509cert_t"); *verified_ca = ver; } else { ver->next = clone_thing(*cert, "x509cert_t"); ver = ver->next; } ver->next = NULL; } else { libreswan_log("intermediate cacert rejected"); free_x509cert(cert); } } /* now verify the end certificates */ pp = firstcert; while (*pp != NULL) { realtime_t valid_until; x509cert_t *cert = *pp; if (verify_x509cert(cert, strict, &valid_until, NULL)) { DBG(DBG_X509 | DBG_PARSING, DBG_log("public key validated")); add_x509_public_key(NULL, cert, valid_until, DAL_SIGNED); } else { libreswan_log("X.509 certificate rejected"); } *pp = cert->next; free_x509cert(cert); } }
main(int argc, char *argv[]) { int i; chunk_t blob, crl_uri; err_t e; cert_t cacert,t1; time_t until; /* sadly, this is actually too late */ EF_DISABLE_BANNER = 1; progname = argv[0]; leak_detective=1; tool_init_log(); load_oswcrypto(); set_debugging(DBG_X509|DBG_PARSING|DBG_CONTROL); until =1421896274; set_fake_x509_time(until); /* Wed Jan 21 22:11:14 2015 */ #ifdef HAVE_LIBNSS { SECStatus nss_init_status= NSS_InitReadWrite("nss.d"); if (nss_init_status != SECSuccess) { fprintf(stderr, "NSS initialization failed (err %d)\n", PR_GetError()); exit(10); } else { printf("NSS Initialized\n"); PK11_SetPasswordFunc(getNSSPassword); } } #endif if(argc < 3) { fprintf(stderr, "Usage: nsscert CAcertfile.pem cert1.pem cert2.pem...\n"); exit(5); } /* skip argv0 */ argc--; argv++; /* load CAcert */ if(!load_cert(CERT_NONE, argv[0], TRUE, "cacert", &cacert)) { printf("could not load CA cert file: %s\n", argv[0]); exit(1); } add_authcert(cacert.u.x509, AUTH_CA); argc--; argv++; while(argc-- > 0) { char *file = *argv++; /* load target cert */ if(!load_cert(CERT_NONE, file, TRUE, "test1", &t1)) { printf("could not load cert file: %s\n", file); exit(1); } until += 86400; if(verify_x509cert(t1.u.x509, FALSE, &until) == FALSE) { printf("verify x509 failed\n"); exit(3); } printf("cert: %s is valid\n", file); free_x509cert(t1.u.x509); } free_x509cert(cacert.u.x509); report_leaks(); tool_close_log(); exit(0); }