END_TEST START_TEST(test_chunk_from_fd_skt) { chunk_t in, contents = chunk_from_chars(0x01,0x02,0x03,0x04,0x05); int s[2]; ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0); ck_assert(write(s[1], contents.ptr, contents.len) == contents.len); close(s[1]); ck_assert_msg(chunk_from_fd(s[0], &in), "%s", strerror(errno)); close(s[0]); ck_assert_msg(chunk_equals(in, contents), "%B", &in); free(in.ptr); }
END_TEST /******************************************************************************* * test for chunk_from_fd */ START_TEST(test_chunk_from_fd_file) { chunk_t in, contents = chunk_from_chars(0x01,0x02,0x03,0x04,0x05); char *path = "/tmp/strongswan-chunk-fd-test"; int fd; ck_assert(chunk_write(contents, path, 022, TRUE)); fd = open(path, O_RDONLY); ck_assert(fd != -1); ck_assert(chunk_from_fd(fd, &in)); close(fd); ck_assert_msg(chunk_equals(in, contents), "%B", &in); unlink(path); free(in.ptr); }
/** * Extract subject DN */ static int dn() { identification_t *id; certificate_t *cert; chunk_t chunk; enum { FORMAT_CONFIG, FORMAT_HEX, FORMAT_BASE64, FORMAT_BINARY, } format = FORMAT_CONFIG; char *arg, *file = NULL, *fmt; while (TRUE) { switch (command_getopt(&arg)) { case 'h': return command_usage(NULL); case 'f': if (streq(arg, "hex")) { format = FORMAT_HEX; } else if (streq(arg, "base64")) { format = FORMAT_BASE64; } else if (streq(arg, "bin")) { format = FORMAT_BINARY; } else if (!streq(arg, "config")) { return command_usage( "invalid output format"); } continue; case 'i': file = arg; continue; case EOF: break; default: return command_usage("invalid --print option"); } break; } if (file) { cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_FROM_FILE, file, BUILD_END); } else { chunk_t chunk; set_file_mode(stdin, CERT_ASN1_DER); if (!chunk_from_fd(0, &chunk)) { fprintf(stderr, "reading input failed: %s\n", strerror(errno)); return 1; } cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_BLOB, chunk, BUILD_END); free(chunk.ptr); } if (!cert) { fprintf(stderr, "parsing input failed\n"); return 1; } id = cert->get_subject(cert); if (!id) { fprintf(stderr, "failed to get certificate's subject DN\n"); cert->destroy(cert); return 1; } fmt = "%.*s\n"; switch (format) { case FORMAT_CONFIG: fmt = "\"asn1dn:#%.*s\"\n"; /* fall-through */ case FORMAT_HEX: chunk = chunk_to_hex(id->get_encoding(id), NULL, FALSE); printf(fmt, (int)chunk.len, chunk.ptr); chunk_free(&chunk); break; case FORMAT_BASE64: chunk = chunk_to_base64(id->get_encoding(id), NULL); printf(fmt, (int)chunk.len, chunk.ptr); chunk_free(&chunk); break; case FORMAT_BINARY: chunk = id->get_encoding(id); if (fwrite(chunk.ptr, chunk.len, 1, stdout) != 1) { fprintf(stderr, "writing subject DN failed\n"); } break; } cert->destroy(cert); return 0; }
/** * Verify a certificate signature */ static int verify() { certificate_t *cert, *ca; char *file = NULL, *cafile = NULL; bool good = FALSE; char *arg; while (TRUE) { switch (command_getopt(&arg)) { case 'h': return command_usage(NULL); case 'i': file = arg; continue; case 'c': cafile = arg; continue; case EOF: break; default: return command_usage("invalid --verify option"); } break; } if (file) { cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_FROM_FILE, file, BUILD_END); } else { chunk_t chunk; chunk = chunk_from_fd(0); cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_BLOB, chunk, BUILD_END); free(chunk.ptr); } if (!cert) { fprintf(stderr, "parsing certificate failed\n"); return 1; } if (cafile) { ca = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_FROM_FILE, cafile, BUILD_END); if (!ca) { fprintf(stderr, "parsing CA certificate failed\n"); return 1; } } else { ca = cert; } if (cert->issued_by(cert, ca, NULL)) { if (cert->get_validity(cert, NULL, NULL, NULL)) { if (cafile) { if (ca->get_validity(ca, NULL, NULL, NULL)) { printf("signature good, certificates valid\n"); good = TRUE; } else { printf("signature good, CA certificates not valid now\n"); } } else { printf("signature good, certificate valid\n"); good = TRUE; } } else { printf("certificate not valid now\n"); } } else { printf("signature invalid\n"); } if (cafile) { ca->destroy(ca); } cert->destroy(cert); return good ? 0 : 2; }
/** * Calculate the keyid of a key/certificate */ static int keyid() { credential_type_t type = CRED_PRIVATE_KEY; int subtype = KEY_ANY; certificate_t *cert; private_key_t *private; public_key_t *public; char *file = NULL; void *cred; chunk_t id; char *arg; while (TRUE) { switch (command_getopt(&arg)) { case 'h': return command_usage(NULL); case 't': if (streq(arg, "rsa") || streq(arg, "rsa-priv")) { type = CRED_PRIVATE_KEY; subtype = KEY_RSA; } else if (streq(arg, "ecdsa") || streq(arg, "ecdsa-priv")) { type = CRED_PRIVATE_KEY; subtype = KEY_ECDSA; } else if (streq(arg, "bliss") || streq(arg, "bliss-priv")) { type = CRED_PRIVATE_KEY; subtype = KEY_BLISS; } else if (streq(arg, "priv")) { type = CRED_PRIVATE_KEY; subtype = KEY_ANY; } else if (streq(arg, "pub")) { type = CRED_PUBLIC_KEY; subtype = KEY_ANY; } else if (streq(arg, "pkcs10")) { type = CRED_CERTIFICATE; subtype = CERT_PKCS10_REQUEST; } else if (streq(arg, "x509")) { type = CRED_CERTIFICATE; subtype = CERT_X509; } else { return command_usage( "invalid input type"); } continue; case 'i': file = arg; continue; case EOF: break; default: return command_usage("invalid --keyid option"); } break; } if (file) { cred = lib->creds->create(lib->creds, type, subtype, BUILD_FROM_FILE, file, BUILD_END); } else { chunk_t chunk; set_file_mode(stdin, CERT_ASN1_DER); if (!chunk_from_fd(0, &chunk)) { fprintf(stderr, "reading input failed: %s\n", strerror(errno)); return 1; } cred = lib->creds->create(lib->creds, type, subtype, BUILD_BLOB, chunk, BUILD_END); free(chunk.ptr); } if (!cred) { fprintf(stderr, "parsing input failed\n"); return 1; } if (type == CRED_PRIVATE_KEY) { private = cred; if (private->get_fingerprint(private, KEYID_PUBKEY_SHA1, &id)) { printf("subjectKeyIdentifier: %#B\n", &id); } if (private->get_fingerprint(private, KEYID_PUBKEY_INFO_SHA1, &id)) { printf("subjectPublicKeyInfo hash: %#B\n", &id); } private->destroy(private);
/** * Verify a certificate signature */ static int verify() { bool trusted = FALSE, valid = FALSE, revoked = FALSE; bool has_ca = FALSE, online = FALSE; certificate_t *cert; enumerator_t *enumerator; auth_cfg_t *auth; mem_cred_t *creds; char *arg, *file = NULL; creds = mem_cred_create(); lib->credmgr->add_set(lib->credmgr, &creds->set); while (TRUE) { switch (command_getopt(&arg)) { case 'h': creds->destroy(creds); return command_usage(NULL); case 'i': file = arg; continue; case 'c': if (load_certs(creds, arg, CERT_X509)) { has_ca = TRUE; } continue; case 'l': if (load_certs(creds, arg, CERT_X509_CRL)) { online = TRUE; } continue; case 'o': online = TRUE; continue; case EOF: break; default: creds->destroy(creds); return command_usage("invalid --verify option"); } break; } if (file) { cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_FROM_FILE, file, BUILD_END); } else { chunk_t chunk; set_file_mode(stdin, CERT_ASN1_DER); if (!chunk_from_fd(0, &chunk)) { fprintf(stderr, "reading certificate failed: %s\n", strerror(errno)); goto end; } cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_BLOB, chunk, BUILD_END); free(chunk.ptr); } if (!cert) { fprintf(stderr, "parsing certificate failed\n"); goto end; } cert = creds->add_cert_ref(creds, !has_ca, cert); enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY, cert->get_subject(cert), online); if (enumerator->enumerate(enumerator, &cert, &auth)) { trusted = TRUE; if (cert->get_validity(cert, NULL, NULL, NULL)) { printf("certificate trusted, lifetimes valid"); valid = TRUE; } else { printf("certificate trusted, but no valid lifetime"); } if (online) { switch ((uintptr_t)auth->get(auth, AUTH_RULE_CRL_VALIDATION)) { case VALIDATION_GOOD: printf(", certificate not revoked"); break; case VALIDATION_SKIPPED: printf(", no revocation information"); break; case VALIDATION_STALE: printf(", revocation information stale"); break; case VALIDATION_FAILED: printf(", revocation checking failed"); break; case VALIDATION_ON_HOLD: printf(", certificate revocation on hold"); revoked = TRUE; break; case VALIDATION_REVOKED: printf(", certificate revoked"); revoked = TRUE; break; } } printf("\n"); } enumerator->destroy(enumerator); cert->destroy(cert); if (!trusted) { printf("certificate untrusted\n"); } end: lib->credmgr->remove_set(lib->credmgr, &creds->set); creds->destroy(creds); if (!trusted) { return 1; } if (!valid) { return 2; } if (revoked) { return 3; } return 0; }