Annotation of embedaddon/strongswan/src/pki/commands/verify.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2016-2018 Tobias Brunner
3: * Copyright (C) 2009 Martin Willi
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * This program is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2 of the License, or (at your
9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10: *
11: * This program is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14: * for more details.
15: */
16:
17: #include <sys/types.h>
18: #include <sys/stat.h>
19: #include <unistd.h>
20: #include <errno.h>
21:
22: #include "pki.h"
23:
24: #include <credentials/certificates/certificate.h>
25: #include <credentials/certificates/x509.h>
26: #include <credentials/sets/mem_cred.h>
27:
28: /**
29: * Load a CA or CRL and add it to the credential set
30: */
31: static bool load_cert(mem_cred_t *creds, char *path, certificate_type_t subtype)
32: {
33: certificate_t *cert;
34: char *credname;
35:
36: switch (subtype)
37: {
38: case CERT_X509:
39: credname = "CA certificate";
40: break;
41: case CERT_X509_CRL:
42: credname = "CRL";
43: break;
44: default:
45: return FALSE;
46: }
47: cert = lib->creds->create(lib->creds,
48: CRED_CERTIFICATE, subtype,
49: BUILD_FROM_FILE, path, BUILD_END);
50: if (!cert)
51: {
52: fprintf(stderr, "parsing %s from '%s' failed\n", credname, path);
53: return FALSE;
54: }
55: if (subtype == CERT_X509_CRL)
56: {
57: creds->add_crl(creds, (crl_t*)cert);
58: }
59: else
60: {
61: creds->add_cert(creds, TRUE, cert);
62: }
63: return TRUE;
64: }
65:
66: /**
67: * Load CA cert or CRL either from a file or a path
68: */
69: static bool load_certs(mem_cred_t *creds, char *path,
70: certificate_type_t subtype)
71: {
72: enumerator_t *enumerator;
73: struct stat st;
74: bool loaded = FALSE;
75:
76: if (stat(path, &st))
77: {
78: fprintf(stderr, "failed to access '%s': %s\n", path, strerror(errno));
79: return FALSE;
80: }
81: if (S_ISDIR(st.st_mode))
82: {
83: enumerator = enumerator_create_directory(path);
84: if (!enumerator)
85: {
86: fprintf(stderr, "directory '%s' can not be opened: %s",
87: path, strerror(errno));
88: return FALSE;
89: }
90: while (enumerator->enumerate(enumerator, NULL, &path, &st))
91: {
92: if (S_ISREG(st.st_mode) && load_cert(creds, path, subtype))
93: {
94: loaded = TRUE;
95: }
96: }
97: enumerator->destroy(enumerator);
98: }
99: else
100: {
101: loaded = load_cert(creds, path, subtype);
102: }
103: return loaded;
104: }
105:
106: /**
107: * Verify a certificate signature
108: */
109: static int verify()
110: {
111: bool trusted = FALSE, valid = FALSE, revoked = FALSE;
112: bool has_ca = FALSE, online = FALSE;
113: certificate_t *cert;
114: enumerator_t *enumerator;
115: auth_cfg_t *auth;
116: mem_cred_t *creds;
117: char *arg, *file = NULL;
118:
119: creds = mem_cred_create();
120: lib->credmgr->add_set(lib->credmgr, &creds->set);
121:
122: while (TRUE)
123: {
124: switch (command_getopt(&arg))
125: {
126: case 'h':
127: creds->destroy(creds);
128: return command_usage(NULL);
129: case 'i':
130: file = arg;
131: continue;
132: case 'c':
133: if (load_certs(creds, arg, CERT_X509))
134: {
135: has_ca = TRUE;
136: }
137: continue;
138: case 'l':
139: if (load_certs(creds, arg, CERT_X509_CRL))
140: {
141: online = TRUE;
142: }
143: continue;
144: case 'o':
145: online = TRUE;
146: continue;
147: case EOF:
148: break;
149: default:
150: creds->destroy(creds);
151: return command_usage("invalid --verify option");
152: }
153: break;
154: }
155:
156: if (file)
157: {
158: cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
159: BUILD_FROM_FILE, file, BUILD_END);
160: }
161: else
162: {
163: chunk_t chunk;
164:
165: set_file_mode(stdin, CERT_ASN1_DER);
166: if (!chunk_from_fd(0, &chunk))
167: {
168: fprintf(stderr, "reading certificate failed: %s\n", strerror(errno));
169: goto end;
170: }
171: cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
172: BUILD_BLOB, chunk, BUILD_END);
173: free(chunk.ptr);
174: }
175: if (!cert)
176: {
177: fprintf(stderr, "parsing certificate failed\n");
178: goto end;
179: }
180: cert = creds->add_cert_ref(creds, !has_ca, cert);
181:
182: enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr,
183: KEY_ANY, cert->get_subject(cert), online);
184: if (enumerator->enumerate(enumerator, &cert, &auth))
185: {
186: trusted = TRUE;
187: if (cert->get_validity(cert, NULL, NULL, NULL))
188: {
189: printf("certificate trusted, lifetimes valid");
190: valid = TRUE;
191: }
192: else
193: {
194: printf("certificate trusted, but no valid lifetime");
195: }
196: if (online)
197: {
198: switch ((uintptr_t)auth->get(auth, AUTH_RULE_CRL_VALIDATION))
199: {
200: case VALIDATION_GOOD:
201: printf(", certificate not revoked");
202: break;
203: case VALIDATION_SKIPPED:
204: printf(", no revocation information");
205: break;
206: case VALIDATION_STALE:
207: printf(", revocation information stale");
208: break;
209: case VALIDATION_FAILED:
210: printf(", revocation checking failed");
211: break;
212: case VALIDATION_ON_HOLD:
213: printf(", certificate revocation on hold");
214: revoked = TRUE;
215: break;
216: case VALIDATION_REVOKED:
217: printf(", certificate revoked");
218: revoked = TRUE;
219: break;
220: }
221: }
222: printf("\n");
223: }
224: enumerator->destroy(enumerator);
225: cert->destroy(cert);
226:
227: if (!trusted)
228: {
229: printf("certificate untrusted\n");
230: }
231:
232: end:
233: lib->credmgr->remove_set(lib->credmgr, &creds->set);
234: creds->destroy(creds);
235:
236: if (!trusted)
237: {
238: return 1;
239: }
240: if (!valid)
241: {
242: return 2;
243: }
244: if (revoked)
245: {
246: return 3;
247: }
248: return 0;
249: }
250:
251: /**
252: * Register the command.
253: */
254: static void __attribute__ ((constructor))reg()
255: {
256: command_register((command_t) {
257: verify, 'v', "verify",
258: "verify a certificate using the CA certificate",
259: {"[--in file] [--cacert file] [--crl file]"},
260: {
261: {"help", 'h', 0, "show usage information"},
262: {"in", 'i', 1, "X.509 certificate to verify, default: stdin"},
263: {"cacert", 'c', 1, "CA certificate for trustchain verification"},
264: {"crl", 'l', 1, "CRL for trustchain verification"},
265: {"online", 'o', 0, "enable online CRL/OCSP revocation checking"},
266: }
267: });
268: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>