Bug Summary

File:programs/pluto/keys.c
Warning:line 518, column 3
Value stored to 'stop' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name keys.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/build/quick-libreswan-2/programs/pluto -resource-dir /usr/lib64/clang/13.0.0 -D TimeZoneOffset=timezone -D PIE -D NSS_IPSEC_PROFILE -D XFRM_LIFETIME_DEFAULT=30 -D USE_IKEv1 -D XFRM_SUPPORT -D USE_XFRM_INTERFACE -D USE_DNSSEC -D DEFAULT_DNSSEC_ROOTKEY_FILE="/var/lib/unbound/root.key" -D HAVE_LABELED_IPSEC -D HAVE_SECCOMP -D LIBCURL -D USE_LINUX_AUDIT -D HAVE_NM -D USE_PAM_AUTH -D USE_3DES -D USE_AES -D USE_CAMELLIA -D USE_CHACHA -D USE_DH31 -D USE_MD5 -D USE_SHA1 -D USE_SHA2 -D USE_PRF_AES_XCBC -D USE_NSS_KDF -D DEFAULT_RUNDIR="/run/pluto" -D IPSEC_CONF="/etc/ipsec.conf" -D IPSEC_CONFDDIR="/etc/ipsec.d" -D IPSEC_NSSDIR="/var/lib/ipsec/nss" -D IPSEC_CONFDIR="/etc" -D IPSEC_EXECDIR="/usr/local/libexec/ipsec" -D IPSEC_SBINDIR="/usr/local/sbin" -D IPSEC_VARDIR="/var" -D POLICYGROUPSDIR="/etc/ipsec.d/policies" -D IPSEC_SECRETS_FILE="/etc/ipsec.secrets" -D FORCE_PR_ASSERT -D USE_FORK=1 -D USE_VFORK=0 -D USE_DAEMON=0 -D USE_PTHREAD_SETSCHEDPRIO=1 -D GCC_LINT -D HAVE_LIBCAP_NG -I . -I ../../OBJ.linux.x86_64/programs/pluto -I ../../include -I /usr/include/nss3 -I /usr/include/nspr4 -I /home/build/quick-libreswan-2/programs/pluto/linux-copy -D HERE_FILENAME="programs/pluto/keys.c" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=gnu99 -fdebug-compilation-dir=/home/build/quick-libreswan-2/programs/pluto -ferror-limit 19 -stack-protector 3 -fgnuc-version=4.2.1 -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-01-01-205714-1273399-1 -x c /home/build/quick-libreswan-2/programs/pluto/keys.c
1/*
2 * interfaces to the secrets.c library functions in libswan.
3 * for now, just stupid wrappers!
4 *
5 * Copyright (C) 1998-2001 D. Hugh Redelmeier.
6 * Copyright (C) 2003-2008 Michael Richardson <mcr@xelerance.com>
7 * Copyright (C) 2003-2010 Paul Wouters <paul@xelerance.com>
8 * Copyright (C) 2008 David McCullough <david_mccullough@securecomputing.com>
9 * Copyright (C) 2009 Avesh Agarwal <avagarwa@redhat.com>
10 * Copyright (C) 2010 Tuomo Soini <tis@foobar.fi>
11 * Copyright (C) 2012-2013 Paul Wouters <paul@libreswan.org>
12 * Copyright (C) 2015 Paul Wouters <pwouters@redhat.com>
13 * Copyright (C) 2016, Andrew Cagney <cagney@gnu.org>
14 * Copyright (C) 2017 Vukasin Karadzic <vukasin.karadzic@gmail.com>
15 * Copyright (C) 2018 Sahana Prasad <sahana.prasad07@gmail.com>
16 * Copyright (C) 2019 D. Hugh Redelmeier <hugh@mimosa.com>
17 *
18 * This program is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 2 of the License, or (at your
21 * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
22 *
23 * This program is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 * for more details.
27 *
28 */
29
30#include <unistd.h>
31#include <sys/socket.h>
32#include <netinet/in.h>
33#include <arpa/inet.h>
34#include <resolv.h>
35
36#include "sysdep.h"
37#include "constants.h"
38#include "ip_info.h"
39#include "defs.h"
40#include "id.h"
41#include "x509.h"
42#include "certs.h"
43#include "connections.h" /* needs id.h */
44#include "state.h"
45#include "keys.h"
46#include "log.h"
47#include "whack.h" /* for RC_LOG_SERIOUS */
48#include "timer.h"
49
50#include "fetch.h"
51#include "pluto_x509.h"
52#include "nss_cert_load.h"
53#include "crypt_mac.h"
54#include "nat_traversal.h"
55
56#include <prerror.h>
57#include <prinit.h>
58#include <prmem.h>
59#include <keyhi.h>
60#include <keythi.h>
61#include <pk11pub.h>
62#include <seccomon.h>
63#include <secerr.h>
64#include <secport.h>
65#include <time.h>
66#include "lswconf.h"
67#include "lswnss.h"
68#include "secrets.h"
69#include "ike_alg_hash.h"
70#include "pluto_timing.h"
71
72static struct secret *pluto_secrets = NULL((void*)0);
73
74void load_preshared_secrets(struct logger *logger)
75{
76 const struct lsw_conf_options *oco = lsw_init_options();
77 lsw_load_preshared_secrets(&pluto_secrets, oco->secretsfile, logger);
78}
79
80void free_preshared_secrets(struct logger *logger)
81{
82 lsw_free_preshared_secrets(&pluto_secrets, logger);
83}
84
85static int print_secrets(struct secret *secret,
86 struct private_key_stuff *pks UNUSED__attribute__ ((unused)),
87 void *uservoid)
88{
89 struct show *s = uservoid;
90
91 const char *kind;
92 switch (pks->kind) {
93 case PKK_PSK:
94 kind = "PSK";
95 break;
96 case PKK_RSA:
97 kind = "RSA";
98 break;
99 case PKK_XAUTH:
100 kind = "XAUTH";
101 break;
102 case PKK_ECDSA:
103 kind = "ECDSA";
104 break;
105 default:
106 return 1;
107 }
108
109 struct id_list *ids = lsw_get_idlist(secret);
110
111 int indent = 0;
112 SHOW_JAMBUF(RC_COMMENT, s, buf)for (struct jambuf *buf = show_jambuf(s); buf != ((void*)0); jambuf_to_show
(buf, s, RC_COMMENT), buf = ((void*)0))
{
113 indent = jam(buf, "%5d:", pks->line);
114 jam(buf, " %s ", kind);
115 if (ids == NULL((void*)0)) {
116 jam(buf, "%%any");
117 } else {
118 jam_id_bytes(buf, &ids->id, jam_sanitized_bytes);
119 if (ids->next != NULL((void*)0)) {
120 jam(buf, " ");
121 jam_id_bytes(buf, &ids->next->id, jam_sanitized_bytes);
122 if (ids->next->next != NULL((void*)0)) {
123 jam(buf, " more");
124 }
125 }
126 }
127 }
128
129 const ckaid_t *ckaid = secret_ckaid(secret); /* may be NULL */
130 if (ckaid != NULL((void*)0)) {
131 SHOW_JAMBUF(RC_COMMENT, s, buf)for (struct jambuf *buf = show_jambuf(s); buf != ((void*)0); jambuf_to_show
(buf, s, RC_COMMENT), buf = ((void*)0))
{
132 jam(buf, "%*s ckaid: ", indent, "");
133 jam_ckaid(buf, ckaid);
134 }
135 }
136
137 /* continue loop until end */
138 return 1;
139}
140
141void list_psks(struct show *s)
142{
143 const struct lsw_conf_options *oco = lsw_init_options();
144 show_blank(s);
145 show_comment(s, "List of Pre-shared secrets (from %s)",
146 oco->secretsfile);
147 show_blank(s);
148 lsw_foreach_secret(pluto_secrets, print_secrets, s);
149}
150
151bool_Bool authsig_using_RSA_pubkey(const struct crypt_mac *expected_hash,
152 shunk_t signature,
153 struct pubkey *kr,
154 const struct hash_desc *hash_algo,
155 diag_t *fatal_diag,
156 struct logger *logger)
157{
158 const struct RSA_public_key *k = &kr->u.rsa;
159
160 /* decrypt the signature -- reversing RSA_sign_hash */
161 if (signature.len != kr->size) {
162 /* XXX notification: INVALID_KEY_INFORMATION */
163 *fatal_diag = NULL((void*)0);
164 return false0;
165 }
166
167 SECStatus retVal;
168 if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) {
169 DBG_dump_hunk("NSS RSA: verifying that decrypted signature matches hash: ",{ typeof(*expected_hash) hunk_ = *expected_hash; DBG_dump("NSS RSA: verifying that decrypted signature matches hash: "
, hunk_.ptr, hunk_.len); }
170 *expected_hash){ typeof(*expected_hash) hunk_ = *expected_hash; DBG_dump("NSS RSA: verifying that decrypted signature matches hash: "
, hunk_.ptr, hunk_.len); }
;
171 }
172
173 /*
174 * Create a public key storing all keying material in an
175 * arena. The arena's lifetime is tied to and released by the
176 * key.
177 *
178 * Danger:
179 *
180 * Need to use SECKEY_DestroyPublicKey() to release any
181 * allocated memory; not SECITEM_FreeArena(); and not both!
182 *
183 * A look at SECKEY_DestroyPublicKey()'s source shows that it
184 * releases the allocated public key by freeing the arena,
185 * hence only that is needed.
186 */
187
188 PRArenaPoolPLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE(2048));
189 if (arena == NULL((void*)0)) {
190 *fatal_diag = diag_nss_error("allocating RSA arena");
191 return false0;
192 }
193
194 SECKEYPublicKey *publicKey = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
195 if (publicKey == NULL((void*)0)) {
196 *fatal_diag = diag_nss_error("allocating RSA pubkey");
197 PORT_FreeArena(arena, PR_FALSE0);
198 return false0;
199 }
200
201 publicKey->arena = arena;
202 publicKey->keyType = rsaKey;
203 publicKey->pkcs11Slot = NULL((void*)0);
204 publicKey->pkcs11ID = CK_INVALID_HANDLE0;
205
206 /*
207 * Convert n and e to form the public key in the
208 * SECKEYPublicKey data structure
209 */
210
211 const SECItem nss_n = same_chunk_as_secitem(k->n, siBuffer);
212 retVal = SECITEM_CopyItem(publicKey->arena, &publicKey->u.rsa.modulus, &nss_n);
213 if (retVal != SECSuccess) {
214 llog_nss_error(RC_LOG, logger, "copying 'n' (modulus) to RSA public key");
215 SECKEY_DestroyPublicKey(publicKey);
216 return false0;
217 }
218
219 const SECItem nss_e = same_chunk_as_secitem(k->e, siBuffer);
220 retVal = SECITEM_CopyItem(publicKey->arena, &publicKey->u.rsa.publicExponent, &nss_e);
221 if (retVal != SECSuccess) {
222 llog_nss_error(RC_LOG, logger, "copying 'e' (exponent) to RSA public key");
223 SECKEY_DestroyPublicKey(publicKey);
224 return false0;
225 }
226
227 /*
228 * Convert the signature into raw form (NSS doesn't do const).
229 */
230
231 const SECItem encrypted_signature = {
232 .type = siBuffer,
233 .data = DISCARD_CONST(unsigned char *, signature.ptr)(__extension__({ const unsigned char * tmp = (signature.ptr);
(unsigned char *)(uintptr_t)tmp; }))
,
234 .len = signature.len,
235 };
236
237 if (hash_algo == NULL((void*)0) /* ikev1*/ ||
238 hash_algo == &ike_alg_hash_sha1 /* old style rsa with SHA1*/) {
239 SECItem decrypted_signature = {
240 .type = siBuffer,
241 };
242 if (SECITEM_AllocItem(publicKey->arena, &decrypted_signature,
243 signature.len) == NULL((void*)0)) {
244 llog_nss_error(RC_LOG, logger, "allocating space for decrypted RSA signature");
245 SECKEY_DestroyPublicKey(publicKey);
246 return false0;
247 }
248
249 if (PK11_VerifyRecover(publicKey, &encrypted_signature, &decrypted_signature,
250 lsw_nss_get_password_context(logger)({ struct logger *l_ = logger; l_; })) != SECSuccess) {
251 dbg("NSS RSA verify: decrypting signature is failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NSS RSA verify: decrypting signature is failed"
); } }
;
252 SECKEY_DestroyPublicKey(publicKey);
253 *fatal_diag = NULL((void*)0);
254 return false0;
255 }
256
257 LSWDBGP(DBG_CRYPT, buf)for (_Bool lswlog_p = (cur_debugging & (((lset_t)1 <<
(DBG_CRYPT_IX)))); lswlog_p; lswlog_p = 0) for (char lswbuf[
((size_t)1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_
= ((void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) for (; buf != ((void*)0); jambuf_to_logger(buf
, &failsafe_logger, DEBUG_STREAM), buf = ((void*)0))
{
258 jam_string(buf, "NSS RSA verify: decrypted sig: ");
259 jam_nss_secitem(buf, &decrypted_signature);
260 }
261
262 /* hash at end? See above for length check */
263 passert(decrypted_signature.len >= expected_hash->len)({ _Bool assertion__ = decrypted_signature.len >= expected_hash
->len; if (!assertion__) { where_t here = ({ static const struct
where here = { .func = __func__, .file = "programs/pluto/keys.c"
, .line = 263, }; &here; }); const struct logger *logger_
= &failsafe_logger; llog_passert(logger_, here, "%s", "decrypted_signature.len >= expected_hash->len"
); } (void) 1; })
;
264 uint8_t *start = (decrypted_signature.data
265 + decrypted_signature.len
266 - expected_hash->len);
267 if (!memeq(start, expected_hash->ptr, expected_hash->len)(memcmp((start), (expected_hash->ptr), (expected_hash->
len)) == 0)
) {
268 dbg("RSA Signature NOT verified"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("RSA Signature NOT verified"); } }
;
269 SECKEY_DestroyPublicKey(publicKey);
270 *fatal_diag = NULL((void*)0);
271 return false0;
272 }
273
274 SECKEY_DestroyPublicKey(publicKey);
275 *fatal_diag = NULL((void*)0);
276 return true1;
277 }
278
279 /*
280 * Digital signature scheme with RSA-PSS
281 */
282 const CK_RSA_PKCS_PSS_PARAMS *mech = hash_algo->nss.rsa_pkcs_pss_params;
283 if (!pexpect(mech != NULL)({ _Bool assertion__ = mech != ((void*)0); if (!assertion__) {
where_t here_ = ({ static const struct where here = { .func =
__func__, .file = "programs/pluto/keys.c", .line = 283, }; &
here; }); const struct logger *logger_ = &failsafe_logger
; llog_pexpect(logger_, here_, "%s", "mech != ((void*)0)"); }
assertion__; })
) {
284 dbg("NSS RSA verify: hash algorithm not supported"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NSS RSA verify: hash algorithm not supported"
); } }
;
285 SECKEY_DestroyPublicKey(publicKey);
286 /* internal error? */
287 *fatal_diag = NULL((void*)0);
288 return false0;
289 }
290
291 const SECItem hash_mech_item = {
292 .type = siBuffer,
293 .data = (void*)mech, /* strip const */
294 .len = sizeof(*mech),
295 };
296
297 struct crypt_mac hash_data = *expected_hash; /* cast away const */
298 const SECItem expected_hash_item = {
299 .len = hash_data.len,
300 .data = hash_data.ptr,
301 .type = siBuffer,
302 };
303
304 if (PK11_VerifyWithMechanism(publicKey, CKM_RSA_PKCS_PSS0x0000000DUL,
305 &hash_mech_item, &encrypted_signature,
306 &expected_hash_item,
307 lsw_nss_get_password_context(logger)({ struct logger *l_ = logger; l_; })) != SECSuccess) {
308 dbg("NSS RSA verify: decrypting signature is failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NSS RSA verify: decrypting signature is failed"
); } }
;
309 SECKEY_DestroyPublicKey(publicKey);
310 *fatal_diag = NULL((void*)0);
311 return false0;
312 }
313
314 SECKEY_DestroyPublicKey(publicKey);
315 *fatal_diag = NULL((void*)0);
316 return true1;
317}
318
319/*
320 * Check signature against all RSA public keys we can find. If we
321 * need keys from DNS KEY records, and they haven't been fetched,
322 * return STF_SUSPEND to ask for asynch DNS lookup.
323 *
324 * Note: parameter keys_from_dns contains results of DNS lookup for
325 * key or is NULL indicating lookup not yet tried.
326 *
327 * take_a_crack is a helper function. Mostly forensic. If only we
328 * had coroutines. (XXX: generators).
329 */
330
331struct tac_state {
332 const struct pubkey_type *type;
333 const struct crypt_mac *hash;
334 shunk_t signature;
335 const struct hash_desc *hash_algo;
336 authsig_using_pubkey_fn *try_pubkey;
337 realtime_t now;
338 struct logger *logger;
339 const struct end *remote;
340 const char *cert_origin;
341
342 /*
343 * Both accumulated across calls and used to return the final
344 * result.
345 *
346 * See below.
347 */
348
349 int tried_cnt; /* number of keys tried */
350 char tried[50]; /* keyids of tried public keys */
351 struct jambuf tried_jambuf; /* jambuf for same */
352 struct pubkey *key; /* last key tried, if any */
353 diag_t fatal_diag; /* fatal error from KEY, if any */
354};
355
356/*
357 * Try all keys from PUBKEY_DB.
358 *
359 * Return true when searching should stop (not when it succeeded);
360 * return false when searching can continue.
361 *
362 * Returns FATAL_DIAG KEY tried_cnt
363 * false NULL NULL 0 no key, try again
364 * false NULL NULL >0 no key worked, try again
365 * true <valid> <valid> N/A fatal error caused by KEY
366 * true NULL <valid> N/A KEY worked
367 */
368
369static bool_Bool try_all_keys(const char *cert_origin,
370 struct pubkey_list *pubkey_db,
371 struct tac_state *s)
372{
373 id_buf thatid;
374 dbg("trying all '%s's for %s key that matches ID: %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("trying all '%s's for %s key that matches ID: %s"
, cert_origin, s->type->name, str_id_bytes(&s->remote
->id, jam_raw_bytes, &thatid)); } }
375 cert_origin, s->type->name, str_id(&s->remote->id, &thatid)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("trying all '%s's for %s key that matches ID: %s"
, cert_origin, s->type->name, str_id_bytes(&s->remote
->id, jam_raw_bytes, &thatid)); } }
;
376 s->cert_origin = cert_origin;
377
378 bool_Bool described = false0;
379 for (struct pubkey_list *p = pubkey_db; p != NULL((void*)0); p = p->next) {
380 struct pubkey *key = p->key;
381
382 if (key->type != s->type) {
383 id_buf printkid;
384 dbg(" skipping '%s' with type %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" skipping '%s' with type %s", str_id_bytes(&
key->id, jam_raw_bytes, &printkid), key->type->name
); } }
385 str_id(&key->id, &printkid), key->type->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" skipping '%s' with type %s", str_id_bytes(&
key->id, jam_raw_bytes, &printkid), key->type->name
); } }
;
386 continue;
387 }
388
389 int wildcards; /* value ignored */
390 if (!match_id(&key->id, &s->remote->id, &wildcards)) {
391 id_buf printkid;
392 dbg(" skipping '%s' with wrong ID",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" skipping '%s' with wrong ID", str_id_bytes(
&key->id, jam_raw_bytes, &printkid)); } }
393 str_id(&key->id, &printkid)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" skipping '%s' with wrong ID", str_id_bytes(
&key->id, jam_raw_bytes, &printkid)); } }
;
394 continue;
395 }
396
397 int pl; /* value ignored */
398 if (!trusted_ca_nss(key->issuer, s->remote->ca, &pl)) {
399 id_buf printkid;
400 dn_buf buf;
401 dbg(" skipping '%s' with untrusted CA '%s'",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" skipping '%s' with untrusted CA '%s'", str_id_bytes
(&key->id, jam_raw_bytes, &printkid), str_dn_or_null
(key->issuer, "%any", &buf)); } }
402 str_id(&key->id, &printkid),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" skipping '%s' with untrusted CA '%s'", str_id_bytes
(&key->id, jam_raw_bytes, &printkid), str_dn_or_null
(key->issuer, "%any", &buf)); } }
403 str_dn_or_null(key->issuer, "%any", &buf)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" skipping '%s' with untrusted CA '%s'", str_id_bytes
(&key->id, jam_raw_bytes, &printkid), str_dn_or_null
(key->issuer, "%any", &buf)); } }
;
404 continue;
405 }
406
407 /*
408 * XXX: even though loop above filtered out these
409 * certs, keep this check, at some point the above
410 * loop will be deleted.
411 */
412 if (!is_realtime_epoch(key->until_time) &&
413 realtime_cmp(key->until_time, <, s->now)(realtime_sub_sign(key->until_time, s->now) < 0)) {
414 id_buf printkid;
415 realtime_buf buf;
416 dbg(" skipping '%s' which expired on %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" skipping '%s' which expired on %s", str_id_bytes
(&key->id, jam_raw_bytes, &printkid), str_realtime
(key->until_time, 0, &buf)); } }
417 str_id(&key->id, &printkid),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" skipping '%s' which expired on %s", str_id_bytes
(&key->id, jam_raw_bytes, &printkid), str_realtime
(key->until_time, 0, &buf)); } }
418 str_realtime(key->until_time, /*utc?*/false, &buf)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" skipping '%s' which expired on %s", str_id_bytes
(&key->id, jam_raw_bytes, &printkid), str_realtime
(key->until_time, 0, &buf)); } }
;
419 continue;
420 }
421
422 id_buf printkid;
423 dn_buf buf;
424 const char *keyid_str = str_keyid(*pubkey_keyid(key))(*pubkey_keyid(key)).keyid;
425 dbg(" trying '%s' aka *%s issued by CA '%s'",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" trying '%s' aka *%s issued by CA '%s'", str_id_bytes
(&key->id, jam_raw_bytes, &printkid), keyid_str, str_dn_or_null
(key->issuer, "%any", &buf)); } }
426 str_id(&key->id, &printkid), keyid_str,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" trying '%s' aka *%s issued by CA '%s'", str_id_bytes
(&key->id, jam_raw_bytes, &printkid), keyid_str, str_dn_or_null
(key->issuer, "%any", &buf)); } }
427 str_dn_or_null(key->issuer, "%any", &buf)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" trying '%s' aka *%s issued by CA '%s'", str_id_bytes
(&key->id, jam_raw_bytes, &printkid), keyid_str, str_dn_or_null
(key->issuer, "%any", &buf)); } }
;
428 s->tried_cnt++;
429
430 if (!described) {
431 jam(&s->tried_jambuf, " %s:", cert_origin);
432 described = true1;
433 }
434 jam(&s->tried_jambuf, " *%s", keyid_str);
435
436 logtime_t try_time = logtime_start(s->logger);
437 bool_Bool passed = (s->try_pubkey)(s->hash, s->signature,
438 key, s->hash_algo,
439 &s->fatal_diag, s->logger);
440 logtime_stop(&try_time, "%s() trying a pubkey", __func__);
441
442 if (s->fatal_diag != NULL((void*)0)) {
443 /* already logged */
444 dbg(" '%s' fatal", keyid_str){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" '%s' fatal", keyid_str); } }
;
445 jam(&s->tried_jambuf, "(fatal)");
446 s->key = key; /* also return failing key */
447 return true1; /* stop searching; enough is enough */
448 }
449
450 if (passed) {
451 dbg(" '%s' passed", keyid_str){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" '%s' passed", keyid_str); } }
;
452 s->key = key;
453 return true1; /* stop searching */
454 }
455
456 /* should have been logged */
457 dbg(" '%s' failed", keyid_str){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" '%s' failed", keyid_str); } }
;
458 pexpect(s->key == NULL)({ _Bool assertion__ = s->key == ((void*)0); if (!assertion__
) { where_t here_ = ({ static const struct where here = { .func
= __func__, .file = "programs/pluto/keys.c", .line = 458, };
&here; }); const struct logger *logger_ = &failsafe_logger
; llog_pexpect(logger_, here_, "%s", "s->key == ((void*)0)"
); } assertion__; })
;
459 }
460
461 return false0; /* keep searching */
462}
463
464diag_t authsig_and_log_using_pubkey(struct ike_sa *ike,
465 const struct crypt_mac *hash,
466 shunk_t signature,
467 const struct hash_desc *hash_algo,
468 const struct pubkey_type *type,
469 authsig_using_pubkey_fn *try_pubkey)
470{
471 const struct connection *c = ike->sa.st_connection;
472 struct tac_state s = {
473 /* in */
474 .type = type,
475 .logger = ike->sa.st_logger,
476 .hash = hash,
477 .now = realnow(),
478 .signature = signature,
479 .hash_algo = hash_algo,
480 .remote = &c->spd.that,
481 .try_pubkey = try_pubkey,
482 /* out */
483 .tried_cnt = 0,
484 .key = NULL((void*)0),
485 .fatal_diag = NULL((void*)0),
486 };
487 s.tried_jambuf = ARRAY_AS_JAMBUF(s.tried)array_as_jambuf((s.tried), sizeof(s.tried));
488
489 /* try all appropriate Public keys */
490
491 dn_buf buf;
492 dbg("required %s CA is '%s'", type->name,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("required %s CA is '%s'", type->name, str_dn_or_null
(c->spd.that.ca, "%any", &buf)); } }
493 str_dn_or_null(c->spd.that.ca, "%any", &buf)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("required %s CA is '%s'", type->name, str_dn_or_null
(c->spd.that.ca, "%any", &buf)); } }
;
494
495 passert(ike->sa.st_remote_certs.processed)({ _Bool assertion__ = ike->sa.st_remote_certs.processed; if
(!assertion__) { where_t here = ({ static const struct where
here = { .func = __func__, .file = "programs/pluto/keys.c", .
line = 495, }; &here; }); const struct logger *logger_ = &
failsafe_logger; llog_passert(logger_, here, "%s", "ike->sa.st_remote_certs.processed"
); } (void) 1; })
;
496
497 /*
498 * Prune the expired public keys from the pre-loaded public
499 * key list. But why here, and why not as a separate job?
500 * And why blame the IKE SA as it isn't really its fault?
501 */
502 for (struct pubkey_list **pp = &pluto_pubkeys; *pp != NULL((void*)0); ) {
503 struct pubkey *key = (*pp)->key;
504 if (!is_realtime_epoch(key->until_time) &&
505 realtime_cmp(key->until_time, <, s.now)(realtime_sub_sign(key->until_time, s.now) < 0)) {
506 id_buf printkid;
507 log_state(RC_LOG_SERIOUS, &ike->sa,
508 "cached %s public key '%s' has expired and has been deleted",
509 key->type->name, str_id(&key->id, &printkid)str_id_bytes(&key->id, jam_raw_bytes, &printkid));
510 *pp = free_public_keyentry(*(pp));
511 continue; /* continue with next public key */
512 }
513 pp = &(*pp)->next;
514 }
515
516 bool_Bool stop = try_all_keys("peer", ike->sa.st_remote_certs.pubkey_db, &s);
517 if (!stop) {
518 stop = try_all_keys("preloaded", pluto_pubkeys, &s);
Value stored to 'stop' is never read
519 }
520
521 if (s.fatal_diag != NULL((void*)0)) {
522 passert(s.key != NULL)({ _Bool assertion__ = s.key != ((void*)0); if (!assertion__)
{ where_t here = ({ static const struct where here = { .func
= __func__, .file = "programs/pluto/keys.c", .line = 522, };
&here; }); const struct logger *logger_ = &failsafe_logger
; llog_passert(logger_, here, "%s", "s.key != ((void*)0)"); }
(void) 1; })
;
523 id_buf idb;
524 return diag_diag(&s.fatal_diag, "authentication aborted: problem with '%s': ",
525 str_id(&s.key->id, &idb)str_id_bytes(&s.key->id, jam_raw_bytes, &idb));
526 }
527
528 if (s.key == NULL((void*)0)) {
529 if (s.tried_cnt == 0) {
530 id_buf idb;
531 return diag("authentication failed: no certificate matched %s with %s and '%s'",
532 type->name, hash_algo->common.fqn,
533 str_id(&c->spd.that.id, &idb)str_id_bytes(&c->spd.that.id, jam_raw_bytes, &idb));
534 } else {
535 id_buf idb;
536 return diag("authentication failed: using %s with %s for '%s' tried%s",
537 type->name, hash_algo->common.fqn,
538 str_id(&c->spd.that.id, &idb)str_id_bytes(&c->spd.that.id, jam_raw_bytes, &idb),
539 s.tried);
540 }
541 }
542
543 pexpect(s.key != NULL)({ _Bool assertion__ = s.key != ((void*)0); if (!assertion__)
{ where_t here_ = ({ static const struct where here = { .func
= __func__, .file = "programs/pluto/keys.c", .line = 543, };
&here; }); const struct logger *logger_ = &failsafe_logger
; llog_pexpect(logger_, here_, "%s", "s.key != ((void*)0)"); }
assertion__; })
;
544 pexpect(s.tried_cnt > 0)({ _Bool assertion__ = s.tried_cnt > 0; if (!assertion__) {
where_t here_ = ({ static const struct where here = { .func =
__func__, .file = "programs/pluto/keys.c", .line = 544, }; &
here; }); const struct logger *logger_ = &failsafe_logger
; llog_pexpect(logger_, here_, "%s", "s.tried_cnt > 0"); }
assertion__; })
;
545 LLOG_JAMBUF(RC_LOG_SERIOUS, ike->sa.st_logger, buf)for (char lswbuf[((size_t)1024)], *lswbuf_ = lswbuf; lswbuf_ !=
((void*)0); lswbuf_ = ((void*)0)) for (struct jambuf jambuf =
array_as_jambuf((lswbuf), sizeof(lswbuf)), *buf = &jambuf
; buf != ((void*)0); buf = ((void*)0)) for (({ if (((RC_LOG_SERIOUS
) & NO_PREFIX) == ((lset_t)0) && (((RC_LOG_SERIOUS
) & STREAM_MASK) != DEBUG_STREAM || (cur_debugging & (
((lset_t)1 << (DBG_ADD_PREFIX_IX)))))) { (ike->sa.st_logger
)->object_vec->jam_object_prefix(buf, (ike->sa.st_logger
)->object); } }); buf != ((void*)0); jambuf_to_logger(buf,
(ike->sa.st_logger), RC_LOG_SERIOUS), buf = ((void*)0))
{
546 if (ike->sa.st_ike_versionst_connection->ike_version == IKEv2) {
547 jam(buf, "established IKE SA; ");
548 }
549 jam(buf, "authenticated using %s with %s and %s certificate ",
550 type->name, hash_algo->common.fqn,
551 s.cert_origin);
552 jam(buf, "'");
553 jam_id_bytes(buf, &s.key->id, jam_sanitized_bytes);
554 jam(buf, "'");
555 /* this is so that the cert verified line can be deleted */
556 if (s.key->issuer.ptr != NULL((void*)0)) {
557 jam(buf, " issued by CA '");
558 jam_dn(buf, s.key->issuer, jam_sanitized_bytes);
559 jam(buf, "'");
560 }
561 }
562 pubkey_delref(&ike->sa.st_peer_pubkey, HERE({ static const struct where here = { .func = __func__, .file
= "programs/pluto/keys.c", .line = 562, }; &here; })
);
563 ike->sa.st_peer_pubkey = pubkey_addref(s.key, HERE({ static const struct where here = { .func = __func__, .file
= "programs/pluto/keys.c", .line = 563, }; &here; })
);
564 return NULL((void*)0);
565}
566
567/*
568 * Find the struct secret associated with the combination of me and
569 * the peer. We match the Id (if none, the IP address). Failure is
570 * indicated by a NULL.
571 */
572
573static struct secret *lsw_get_secret(const struct connection *c,
574 enum PrivateKeyKind kind,
575 bool_Bool asym)
576{
577 /* under certain conditions, override that_id to %ANYADDR */
578
579 struct id rw_id;
580 const struct id *const this_id = &c->spd.this.id;
581 const struct id *that_id = &c->spd.that.id; /* can change */
582
583 if (
584 /* case 1: */
585 ( remote_id_was_instantiated(c)( (c)->kind == CK_INSTANCE && ( !((&(c)->spd
.that.id)->kind == ID_IPV4_ADDR || (&(c)->spd.that.
id)->kind == ID_IPV6_ADDR) || sameaddr(&(c)->spd.that
.id.ip_addr, &(c)->spd.that.host_addr) ) )
&&
586 !(c->policy & POLICY_AGGRESSIVE((lset_t)1 << (POLICY_AGGRESSIVE_IX))) &&
587 (address_is_unset(&c->spd.that.host_addr) ||
588 address_is_any(c->spd.that.host_addr)) ) ||
589
590 /* case 2 */
591 ( (c->policy & POLICY_PSK((lset_t)1 << (POLICY_PSK_IX))) &&
592 kind == PKK_PSK &&
593 ( ( c->kind == CK_TEMPLATE &&
594 c->spd.that.id.kind == ID_NONE ) ||
595 ( c->kind == CK_INSTANCE &&
596 id_is_ipaddr(&c->spd.that.id)((&c->spd.that.id)->kind == ID_IPV4_ADDR || (&c
->spd.that.id)->kind == ID_IPV6_ADDR)
&&
597 /* Check if we are a road warrior instantiation, not a vnet: instantiation */
598 (address_is_unset(&c->spd.that.host_addr) ||
599 address_is_any(c->spd.that.host_addr)) ) ) )
600 ) {
601 /* roadwarrior: replace that with %ANYADDR */
602 rw_id.kind = address_type(&c->spd.that.host_addr)->id_ip_addr;
603 rw_id.ip_addr = address_type(&c->spd.that.host_addr)->address.any;
604 id_buf old_buf, new_buf;
605 dbg("%s() switching remote roadwarrier ID from %s to %s (%%ANYADDR)",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() switching remote roadwarrier ID from %s to %s (%%ANYADDR)"
, __func__, str_id_bytes(that_id, jam_raw_bytes, &old_buf
), str_id_bytes(&rw_id, jam_raw_bytes, &new_buf)); } }
606 __func__, str_id(that_id, &old_buf), str_id(&rw_id, &new_buf)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() switching remote roadwarrier ID from %s to %s (%%ANYADDR)"
, __func__, str_id_bytes(that_id, jam_raw_bytes, &old_buf
), str_id_bytes(&rw_id, jam_raw_bytes, &new_buf)); } }
;
607 that_id = &rw_id;
608
609 }
610
611 id_buf this_buf, that_buf;
612 dbg("%s() using IDs for %s->%s of kind %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using IDs for %s->%s of kind %s", __func__
, str_id_bytes(this_id, jam_raw_bytes, &this_buf), str_id_bytes
(that_id, jam_raw_bytes, &that_buf), enum_name(&pkk_names
, kind)); } }
613 __func__,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using IDs for %s->%s of kind %s", __func__
, str_id_bytes(this_id, jam_raw_bytes, &this_buf), str_id_bytes
(that_id, jam_raw_bytes, &that_buf), enum_name(&pkk_names
, kind)); } }
614 str_id(this_id, &this_buf),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using IDs for %s->%s of kind %s", __func__
, str_id_bytes(this_id, jam_raw_bytes, &this_buf), str_id_bytes
(that_id, jam_raw_bytes, &that_buf), enum_name(&pkk_names
, kind)); } }
615 str_id(that_id, &that_buf),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using IDs for %s->%s of kind %s", __func__
, str_id_bytes(this_id, jam_raw_bytes, &this_buf), str_id_bytes
(that_id, jam_raw_bytes, &that_buf), enum_name(&pkk_names
, kind)); } }
616 enum_name(&pkk_names, kind)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using IDs for %s->%s of kind %s", __func__
, str_id_bytes(this_id, jam_raw_bytes, &this_buf), str_id_bytes
(that_id, jam_raw_bytes, &that_buf), enum_name(&pkk_names
, kind)); } }
;
617
618 return lsw_find_secret_by_id(pluto_secrets, kind,
619 this_id, that_id, asym);
620}
621
622/*
623 * find the struct secret associated with an XAUTH username.
624 */
625struct secret *lsw_get_xauthsecret(char *xauthname)
626{
627 struct secret *best = NULL((void*)0);
628
629 dbg("started looking for xauth secret for %s", xauthname){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("started looking for xauth secret for %s", xauthname
); } }
;
630
631 struct id xa_id = {
632 .kind = ID_FQDN,
633 .name = {
634 .ptr = (unsigned char *)xauthname,
635 .len = strlen(xauthname)
636 }
637 };
638
639 best = lsw_find_secret_by_id(pluto_secrets,
640 PKK_XAUTH,
641 &xa_id, NULL((void*)0), true1);
642
643 return best;
644}
645
646/*
647 * find the appropriate preshared key (see get_secret).
648 * Failure is indicated by a NULL pointer.
649 * Note: the result is not to be freed by the caller.
650 * Note2: this seems to be called for connections using RSA too?
651 */
652
653const chunk_t *get_connection_psk(const struct connection *c)
654{
655 /* caller handles null_auth */
656 passert((c->policy & POLICY_AUTH_NULL) == LEMPTY)({ _Bool assertion__ = (c->policy & ((lset_t)1 <<
(POLICY_AUTH_NULL_IX))) == ((lset_t)0); if (!assertion__) { where_t
here = ({ static const struct where here = { .func = __func__
, .file = "programs/pluto/keys.c", .line = 656, }; &here;
}); const struct logger *logger_ = &failsafe_logger; llog_passert
(logger_, here, "%s", "(c->policy & ((lset_t)1 << (POLICY_AUTH_NULL_IX))) == ((lset_t)0)"
); } (void) 1; })
;
657
658 struct secret *s = lsw_get_secret(c, PKK_PSK, false0);
659 if (s == NULL((void*)0)) {
660 dbg("no PreShared Key Found"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("no PreShared Key Found"); } }
;
661 return NULL((void*)0);
662 }
663
664 const chunk_t *psk = &lsw_get_pks(s)->u.preshared_secret;
665 if (DBGP(DBG_CRYPT)(cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX))))) {
666 DBG_dump_hunk("PreShared Key", *psk){ typeof(*psk) hunk_ = *psk; DBG_dump("PreShared Key", hunk_.
ptr, hunk_.len); }
;
667 }
668 return psk;
669}
670
671
672/* Return ppk and store ppk_id in *ppk_id */
673
674chunk_t *get_connection_ppk(const struct connection *c, chunk_t **ppk_id)
675{
676 struct secret *s = lsw_get_secret(c, PKK_PPK, false0);
677
678 if (s == NULL((void*)0)) {
679 *ppk_id = NULL((void*)0);
680 return NULL((void*)0);
681 }
682
683 struct private_key_stuff *pks = lsw_get_pks(s);
684 *ppk_id = &pks->ppk_id;
685 if (DBGP(DBG_CRYPT)(cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX))))) {
686 DBG_log("Found PPK");
687 DBG_dump_hunk("PPK_ID:", **ppk_id){ typeof(**ppk_id) hunk_ = **ppk_id; DBG_dump("PPK_ID:", hunk_
.ptr, hunk_.len); }
;
688 DBG_dump_hunk("PPK:", pks->ppk){ typeof(pks->ppk) hunk_ = pks->ppk; DBG_dump("PPK:", hunk_
.ptr, hunk_.len); }
;
689 }
690 return &pks->ppk;
691}
692
693/*
694 * Find PPK, by its id (PPK_ID).
695 * Used by responder.
696 */
697const chunk_t *get_ppk_by_id(const chunk_t *ppk_id)
698{
699 struct secret *s = lsw_get_ppk_by_id(pluto_secrets, *ppk_id);
700
701 if (s != NULL((void*)0)) {
702 const struct private_key_stuff *pks = lsw_get_pks(s);
703 if (DBGP(DBG_CRYPT)(cur_debugging & (((lset_t)1 << (DBG_CRYPT_IX))))) {
704 DBG_dump_hunk("Found PPK:", pks->ppk){ typeof(pks->ppk) hunk_ = pks->ppk; DBG_dump("Found PPK:"
, hunk_.ptr, hunk_.len); }
;
705 DBG_dump_hunk("with PPK_ID:", *ppk_id){ typeof(*ppk_id) hunk_ = *ppk_id; DBG_dump("with PPK_ID:", hunk_
.ptr, hunk_.len); }
;
706 }
707 return &pks->ppk;
708 }
709 dbg("No PPK found with given PPK_ID"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("No PPK found with given PPK_ID"); } }
;
710 return NULL((void*)0);
711}
712
713/*
714 * Find the appropriate private key (see get_secret). Failure is
715 * indicated by a NULL pointer.
716 */
717
718const struct private_key_stuff *get_connection_private_key(const struct connection *c,
719 const struct pubkey_type *type,
720 struct logger *logger)
721{
722 /* is there a certificate assigned to this connection? */
723 if (c->spd.this.cert.nss_cert != NULL((void*)0)) {
724 const char *nickname = cert_nickname(&c->spd.this.cert);
725
726 id_buf this_buf, that_buf;
727 dbg("%s() using certificate %s to find private key for %s->%s of kind %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using certificate %s to find private key for %s->%s of kind %s"
, __func__, nickname, str_id_bytes(&c->spd.this.id, jam_raw_bytes
, &this_buf), str_id_bytes(&c->spd.that.id, jam_raw_bytes
, &that_buf), type->name); } }
728 __func__, nickname,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using certificate %s to find private key for %s->%s of kind %s"
, __func__, nickname, str_id_bytes(&c->spd.this.id, jam_raw_bytes
, &this_buf), str_id_bytes(&c->spd.that.id, jam_raw_bytes
, &that_buf), type->name); } }
729 str_id(&c->spd.this.id, &this_buf),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using certificate %s to find private key for %s->%s of kind %s"
, __func__, nickname, str_id_bytes(&c->spd.this.id, jam_raw_bytes
, &this_buf), str_id_bytes(&c->spd.that.id, jam_raw_bytes
, &that_buf), type->name); } }
730 str_id(&c->spd.that.id, &that_buf),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using certificate %s to find private key for %s->%s of kind %s"
, __func__, nickname, str_id_bytes(&c->spd.this.id, jam_raw_bytes
, &this_buf), str_id_bytes(&c->spd.that.id, jam_raw_bytes
, &that_buf), type->name); } }
731 type->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using certificate %s to find private key for %s->%s of kind %s"
, __func__, nickname, str_id_bytes(&c->spd.this.id, jam_raw_bytes
, &this_buf), str_id_bytes(&c->spd.that.id, jam_raw_bytes
, &that_buf), type->name); } }
;
732
733 const struct private_key_stuff *pks = NULL((void*)0);
734 bool_Bool load_needed;
735 err_t err = find_or_load_private_key_by_cert(&pluto_secrets, &c->spd.this.cert,
736 &pks, &load_needed, logger);
737 if (err != NULL((void*)0)) {
738 dbg("private key for certificate %s not found in NSS DB",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("private key for certificate %s not found in NSS DB"
, nickname); } }
739 nickname){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("private key for certificate %s not found in NSS DB"
, nickname); } }
;
740 return NULL((void*)0);
741 } else if (load_needed) {
742 /*
743 * XXX: the private key that was pre-loaded
744 * during "whack add" may have been deleted
745 * because all secrets were thrown away.
746 *
747 * The real problem is that the connection
748 * lacks a counted reference to the private
749 * key.
750 */
751 llog(RC_LOG|LOG_STREAM/*not-whack-grrr*/, logger,
752 "reloaded private key matching %s certificate '%s'",
753 c->spd.this.config->leftright, nickname);
754 }
755
756 /*
757 * If we don't find the right keytype (RSA, ECDSA,
758 * etc) then best will end up as NULL
759 */
760 dbg("connection %s's %s private key found in NSS DB using cert",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("connection %s's %s private key found in NSS DB using cert"
, c->name, type->name); } }
761 c->name, type->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("connection %s's %s private key found in NSS DB using cert"
, c->name, type->name); } }
;
762 return pks;
763 }
764
765 /* is there a CKAID assigned to this connection? */
766 if (c->spd.this.ckaid != NULL((void*)0)) {
767 ckaid_buf ckb;
768 id_buf this_buf, that_buf;
769 dbg("%s() using CKAID %s to find private key for %s->%s of kind %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using CKAID %s to find private key for %s->%s of kind %s"
, __func__, str_ckaid(c->spd.this.ckaid, &ckb), str_id_bytes
(&c->spd.this.id, jam_raw_bytes, &this_buf), str_id_bytes
(&c->spd.that.id, jam_raw_bytes, &that_buf), type->
name); } }
770 __func__, str_ckaid(c->spd.this.ckaid, &ckb),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using CKAID %s to find private key for %s->%s of kind %s"
, __func__, str_ckaid(c->spd.this.ckaid, &ckb), str_id_bytes
(&c->spd.this.id, jam_raw_bytes, &this_buf), str_id_bytes
(&c->spd.that.id, jam_raw_bytes, &that_buf), type->
name); } }
771 str_id(&c->spd.this.id, &this_buf),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using CKAID %s to find private key for %s->%s of kind %s"
, __func__, str_ckaid(c->spd.this.ckaid, &ckb), str_id_bytes
(&c->spd.this.id, jam_raw_bytes, &this_buf), str_id_bytes
(&c->spd.that.id, jam_raw_bytes, &that_buf), type->
name); } }
772 str_id(&c->spd.that.id, &that_buf),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using CKAID %s to find private key for %s->%s of kind %s"
, __func__, str_ckaid(c->spd.this.ckaid, &ckb), str_id_bytes
(&c->spd.this.id, jam_raw_bytes, &this_buf), str_id_bytes
(&c->spd.that.id, jam_raw_bytes, &that_buf), type->
name); } }
773 type->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() using CKAID %s to find private key for %s->%s of kind %s"
, __func__, str_ckaid(c->spd.this.ckaid, &ckb), str_id_bytes
(&c->spd.this.id, jam_raw_bytes, &this_buf), str_id_bytes
(&c->spd.that.id, jam_raw_bytes, &that_buf), type->
name); } }
;
774
775 const struct private_key_stuff *pks;
776 bool_Bool load_needed;
777 err_t err = find_or_load_private_key_by_ckaid(&pluto_secrets, c->spd.this.ckaid,
778 &pks, &load_needed, logger);
779 if (err != NULL((void*)0)) {
780 ckaid_buf ckb;
781 llog(RC_LOG_SERIOUS, logger,
782 "private key matching CKAID '%s' not found: %s",
783 str_ckaid(c->spd.this.ckaid, &ckb), err);
784 return NULL((void*)0);
785 } else if (load_needed) {
786 /*
787 * XXX: the private key that was pre-loaded
788 * during "whack add" may have been deleted
789 * because all secrets were thrown away.
790 *
791 * The real problem is that the connection
792 * lacks a counted reference to the private
793 * key.
794 */
795 ckaid_buf ckb;
796 llog(RC_LOG|LOG_STREAM/*not-whack-grr*/, logger,
797 "reloaded private key matching %s CKAID %s",
798 c->spd.this.config->leftright, str_ckaid(c->spd.this.ckaid, &ckb));
799 }
800
801
802 /*
803 * If we don't find the right keytype (RSA, ECDSA,
804 * etc) then best will end up as NULL
805 */
806 dbg("connection %s's %s private key found in NSS DB using CKAID",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("connection %s's %s private key found in NSS DB using CKAID"
, c->name, type->name); } }
807 c->name, type->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("connection %s's %s private key found in NSS DB using CKAID"
, c->name, type->name); } }
;
808 return pks;
809 }
810
811 dbg("looking for connection %s's %s private key",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("looking for connection %s's %s private key", c
->name, type->name); } }
812 c->name, type->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("looking for connection %s's %s private key", c
->name, type->name); } }
;
813 struct secret *s = lsw_get_secret(c, type->private_key_kind, true1);
814 if (s == NULL((void*)0)) {
815 llog(RC_LOG_SERIOUS, logger, "connection %s's %s private key not found",
816 c->name, type->name);
817 return NULL((void*)0);
818 }
819
820 const struct private_key_stuff *pks = lsw_get_pks(s);
821 passert(pks != NULL)({ _Bool assertion__ = pks != ((void*)0); if (!assertion__) {
where_t here = ({ static const struct where here = { .func =
__func__, .file = "programs/pluto/keys.c", .line = 821, }; &
here; }); const struct logger *logger_ = &failsafe_logger
; llog_passert(logger_, here, "%s", "pks != ((void*)0)"); } (
void) 1; })
;
822
823 dbg("connection %s's %s private key found",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("connection %s's %s private key found", c->
name, type->name); } }
824 c->name, type->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("connection %s's %s private key found", c->
name, type->name); } }
;
825 return pks;
826}
827
828/*
829 * public key machinery
830 */
831
832/* root of chained public key list */
833
834struct pubkey_list *pluto_pubkeys = NULL((void*)0); /* keys from ipsec.conf */
835
836void free_remembered_public_keys(void)
837{
838 free_public_keys(&pluto_pubkeys);
839}
840
841/*
842 * list all public keys in the chained list
843 */
844
845/*
846 * checks if the expiration date has been reached and warns during the
847 * warning_interval of the imminent expiry.
848 *
849 * warning interval is in days.
850 *
851 * strict == TRUE: expiry yields an error message
852 * strict == FALSE: expiry yields a warning message
853 */
854
855typedef struct {
856 /* note: 20 is a guess at the maximum digits in an intmax_t */
857 char buf[sizeof("warning (expires in %jd minutes)") + 20];
858} expiry_buf;
859
860static const char *check_expiry(realtime_t expiration_date, time_t warning_interval, expiry_buf *eb)
861{
862 if (is_realtime_epoch(expiration_date))
863 return "ok (expires never)";
864
865 time_t time_left = deltasecs(realtimediff(expiration_date, realnow()));
866
867 if (time_left < 0)
868 return "fatal (expired)";
869
870 if (time_left > warning_interval)
871 return NULL((void*)0);
872
873 const char *unit;
874 if (time_left > 2 * secs_per_day) {
875 time_left /= secs_per_day;
876 unit = "day";
877 } else if (time_left > 2 * secs_per_hour) {
878 time_left /= secs_per_hour;
879 unit = "hour";
880 } else if (time_left > 2 * secs_per_minute) {
881 time_left /= secs_per_minute;
882 unit = "minute";
883 } else {
884 unit = "second";
885 }
886
887 snprintf(eb->buf, sizeof(eb->buf), "warning (expires in %jd %s%s)",
888 (intmax_t) time_left, unit,
889 (time_left == 1) ? "" : "s");
890 return eb->buf;
891}
892
893static void show_pubkey(struct show *s, struct pubkey *key, bool_Bool utc, const char *expiry_message)
894{
895 bool_Bool load_needed;
896 err_t load_err = preload_private_key_by_ckaid(&key->ckaid,
897 &load_needed,
898 show_logger(s));
899 SHOW_JAMBUF(RC_COMMENT, s, buf)for (struct jambuf *buf = show_jambuf(s); buf != ((void*)0); jambuf_to_show
(buf, s, RC_COMMENT), buf = ((void*)0))
{
900 jam_realtime(buf, key->installed_time, utc);
901 jam(buf, ",");
902 jam(buf, " %4zd", 8 * key->size);
903 jam(buf, " %s", key->type->name);
904 jam(buf, " Key %s", str_keyid(key->keyid)(key->keyid).keyid);
905 jam(buf, " (%s private key),",
906 (load_err != NULL((void*)0) ? "no" :
907 load_needed ? "loaded" : "has"));
908 jam(buf, " until ");
909 jam_realtime(buf, key->until_time, utc);
910 jam(buf, " %s", expiry_message == NULL((void*)0) ? "ok" : expiry_message);
911 }
912
913 id_buf idb;
914 esb_buf b;
915 show_comment(s, " %s '%s'",
916 enum_show(&ike_id_type_names, key->id.kind, &b),
917 str_id(&key->id, &idb)str_id_bytes(&key->id, jam_raw_bytes, &idb));
918
919 if (key->issuer.len > 0) {
920 dn_buf b;
921 show_comment(s, " Issuer '%s'",
922 str_dn(key->issuer, &b));
923 }
924}
925
926void show_pubkeys(struct show *s, bool_Bool utc, enum keys_to_show keys_to_show)
927{
928 if (keys_to_show == SHOW_ALL_KEYS) {
929 show_blank(s);
930 show_comment(s, "List of Public Keys:");
931 show_blank(s);
932 }
933
934 for (struct pubkey_list *p = pluto_pubkeys; p != NULL((void*)0); p = p->next) {
935 struct pubkey *pubkey = p->key;
936 expiry_buf eb;
937 const char *expiry_msg = check_expiry(pubkey->until_time, PUBKEY_WARNING_INTERVAL(14 * secs_per_day), &eb);
938 switch (keys_to_show) {
939 case SHOW_ALL_KEYS:
940 show_pubkey(s, pubkey, utc, expiry_msg);
941 break;
942 case SHOW_EXPIRED_KEYS:
943 if (expiry_msg != NULL((void*)0)) {
944 show_pubkey(s, pubkey, utc, expiry_msg);
945 }
946 break;
947 }
948 }
949}
950
951err_t preload_private_key_by_cert(const struct cert *cert, bool_Bool *load_needed, struct logger *logger)
952{
953 threadtime_t start = threadtime_start();
954 const struct private_key_stuff *pks;
955 err_t err = find_or_load_private_key_by_cert(&pluto_secrets, cert,
956 &pks, load_needed, logger);
957 threadtime_stop(&start, SOS_NOBODY0, "%s() loading private key %s", __func__,
958 cert->nss_cert->nickname);
959 return err;
960}
961
962err_t preload_private_key_by_ckaid(const ckaid_t *ckaid, bool_Bool *load_needed, struct logger *logger)
963{
964 threadtime_t start = threadtime_start();
965 const struct private_key_stuff *pks;
966 err_t err = find_or_load_private_key_by_ckaid(&pluto_secrets, ckaid,
967 &pks, load_needed, logger);
968 threadtime_stop(&start, SOS_NOBODY0, "%s() loading private key using CKAID", __func__);
969 return err;
970}
971
972const struct pubkey *find_pubkey_by_ckaid(const char *ckaid)
973{
974 for (struct pubkey_list *p = pluto_pubkeys; p != NULL((void*)0); p = p->next) {
975 DBG_log("looking at a PUBKEY");
976 struct pubkey *key = p->key;
977 const ckaid_t *key_ckaid = pubkey_ckaid(key);
978 if (ckaid_starts_with(key_ckaid, ckaid)) {
979 dbg("ckaid matching pubkey"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ckaid matching pubkey"); } }
;
980 return key;
981 }
982 }
983 return NULL((void*)0);
984}