1 /* mechanisms for preshared keys (public, private, and preshared secrets)
2 * Copyright (C) 1998-2001 D. Hugh Redelmeier.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
26 #include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
27 #include <sys/queue.h>
31 # define GLOB_ABORTED GLOB_ABEND /* fix for old versions */
37 #include <asn1/asn1.h>
39 #include "constants.h"
46 #include "smartcard.h"
47 #include "connections.h"
51 #include "adns.h" /* needs <resolv.h> */
52 #include "dnskey.h" /* needs keys.h and adns.h */
54 #include "whack.h" /* for RC_LOG_SERIOUS */
59 const char *shared_secrets_file
= SHARED_SECRETS_FILE
;
61 typedef struct id_list id_list_t
;
68 typedef struct secret secret_t
;
72 enum PrivateKeyKind kind
;
74 chunk_t preshared_secret
;
76 private_key_t
*private_key
;
77 smartcard_t
*smartcard
;
83 * free a public key struct
85 static void free_public_key(pubkey_t
*pk
)
87 DESTROY_IF(pk
->public_key
);
88 free_id_content(&pk
->id
);
94 secret_t
*secrets
= NULL
;
96 /* find the struct secret associated with the combination of
97 * me and the peer. We match the Id (if none, the IP address).
98 * Failure is indicated by a NULL.
100 static const secret_t
* get_secret(const struct connection
*c
,
101 enum PrivateKeyKind kind
, bool asym
)
104 match_default
= 0x01,
109 unsigned int best_match
= 0;
110 secret_t
*best
= NULL
;
112 const struct id
*my_id
= &c
->spd
.this.id
113 , *his_id
= &c
->spd
.that
.id
;
116 /* is there a certificate assigned to this connection? */
117 if (kind
== PPK_PUBKEY
&& c
->spd
.this.cert
.type
!= CERT_NONE
)
119 public_key_t
*pub_key
= cert_get_public_key(c
->spd
.this.cert
);
121 for (s
= secrets
; s
!= NULL
; s
= s
->next
)
123 if (s
->kind
== kind
&&
124 s
->u
.private_key
->belongs_to(s
->u
.private_key
, pub_key
))
127 break; /* we have found the private key - no sense in searching further */
133 if (his_id_was_instantiated(c
))
135 /* roadwarrior: replace him with 0.0.0.0 */
136 rw_id
.kind
= c
->spd
.that
.id
.kind
;
137 rw_id
.name
= chunk_empty
;
138 happy(anyaddr(addrtypeof(&c
->spd
.that
.host_addr
), &rw_id
.ip_addr
));
141 else if (kind
== PPK_PSK
142 && (c
->policy
& (POLICY_PSK
| POLICY_XAUTH_PSK
))
143 && ((c
->kind
== CK_TEMPLATE
&& c
->spd
.that
.id
.kind
== ID_ANY
) ||
144 (c
->kind
== CK_INSTANCE
&& id_is_ipaddr(&c
->spd
.that
.id
))))
146 /* roadwarrior: replace him with 0.0.0.0 */
147 rw_id
.kind
= ID_IPV4_ADDR
;
148 happy(anyaddr(addrtypeof(&c
->spd
.that
.host_addr
), &rw_id
.ip_addr
));
152 for (s
= secrets
; s
!= NULL
; s
= s
->next
)
156 unsigned int match
= 0;
160 /* a default (signified by lack of ids):
161 * accept if no more specific match found
163 match
= match_default
;
167 /* check if both ends match ids */
170 for (i
= s
->ids
; i
!= NULL
; i
= i
->next
)
172 if (same_id(my_id
, &i
->id
))
176 if (same_id(his_id
, &i
->id
))
182 /* If our end matched the only id in the list,
183 * default to matching any peer.
184 * A more specific match will trump this.
186 if (match
== match_me
&& s
->ids
->next
== NULL
)
188 match
|= match_default
;
195 /* if this is an asymmetric (eg. public key) system,
196 * allow this-side-only match to count, even if
197 * there are other ids in the list.
204 case match_default
: /* default all */
205 case match_me
| match_default
: /* default peer */
206 case match_me
| match_him
: /* explicit */
207 if (match
== best_match
)
209 /* two good matches are equally good:
217 same
= s
->u
.preshared_secret
.len
== best
->u
.preshared_secret
.len
218 && memeq(s
->u
.preshared_secret
.ptr
, best
->u
.preshared_secret
.ptr
, s
->u
.preshared_secret
.len
);
221 same
= s
->u
.private_key
->equals(s
->u
.private_key
, best
->u
.private_key
);
228 loglog(RC_LOG_SERIOUS
, "multiple ipsec.secrets entries with distinct secrets match endpoints:"
229 " first secret used");
230 best
= s
; /* list is backwards: take latest in list */
233 else if (match
> best_match
)
235 /* this is the best match so far */
245 /* find the appropriate preshared key (see get_secret).
246 * Failure is indicated by a NULL pointer.
247 * Note: the result is not to be freed by the caller.
249 const chunk_t
* get_preshared_secret(const struct connection
*c
)
251 const secret_t
*s
= get_secret(c
, PPK_PSK
, FALSE
);
255 DBG_log("no Preshared Key Found");
257 DBG_dump_chunk("Preshared Key", s
->u
.preshared_secret
);
259 return s
== NULL? NULL
: &s
->u
.preshared_secret
;
262 /* check the existence of an RSA private key matching an RSA public
263 * key contained in an X.509 or OpenPGP certificate
265 bool has_private_key(cert_t cert
)
268 bool has_key
= FALSE
;
269 public_key_t
*pub_key
= cert_get_public_key(cert
);
271 for (s
= secrets
; s
!= NULL
; s
= s
->next
)
273 if (s
->kind
== PPK_PUBKEY
&&
274 s
->u
.private_key
->belongs_to(s
->u
.private_key
, pub_key
))
284 * get the matching RSA private key belonging to a given X.509 certificate
286 private_key_t
* get_x509_private_key(const x509cert_t
*cert
)
290 for (s
= secrets
; s
!= NULL
; s
= s
->next
)
292 if (s
->kind
== PPK_PUBKEY
&&
293 s
->u
.private_key
->belongs_to(s
->u
.private_key
, cert
->public_key
))
295 return s
->u
.private_key
;
301 /* find the appropriate RSA private key (see get_secret).
302 * Failure is indicated by a NULL pointer.
304 private_key_t
* get_private_key(const struct connection
*c
)
306 const secret_t
*s
= get_secret(c
, PPK_PUBKEY
, TRUE
);
308 return s
== NULL? NULL
: s
->u
.private_key
;
311 /* digest a secrets file
313 * The file is a sequence of records. A record is a maximal sequence of
314 * tokens such that the first, and only the first, is in the first column
317 * Tokens are generally separated by whitespace and are key words, ids,
318 * strings, or data suitable for ttodata(3). As a nod to convention,
319 * a trailing ":" on what would otherwise be a token is taken as a
320 * separate token. If preceded by whitespace, a "#" is taken as starting
321 * a comment: it and the rest of the line are ignored.
323 * One kind of record is an include directive. It starts with "include".
324 * The filename is the only other token in the record.
325 * If the filename does not start with /, it is taken to
326 * be relative to the directory containing the current file.
328 * The other kind of record describes a key. It starts with a
329 * sequence of ids and ends with key information. Each id
330 * is an IP address, a Fully Qualified Domain Name (which will immediately
331 * be resolved), or @FQDN which will be left as a name.
333 * The key part can be in several forms.
335 * The old form of the key is still supported: a simple
336 * quoted strings (with no escapes) is taken as a preshred key.
338 * The new form starts the key part with a ":".
340 * For Preshared Key, use the "PSK" keyword, and follow it by a string
341 * or a data token suitable for ttodata(3).
343 * For RSA Private Key, use the "RSA" keyword, followed by a
344 * brace-enclosed list of key field keywords and data values.
345 * The data values are large integers to be decoded by ttodata(3).
346 * The fields are a subset of those used by BIND 8.2 and have the
350 /* parse PSK from file */
351 static err_t
process_psk_secret(chunk_t
*psk
)
355 if (*tok
== '"' || *tok
== '\'')
357 chunk_t secret
= { tok
+ 1, flp
->cur
- tok
-2 };
359 *psk
= chunk_clone(secret
);
364 char buf
[BUF_LEN
]; /* limit on size of binary representation of key */
367 ugh
= ttodatav(tok
, flp
->cur
- tok
, 0, buf
, sizeof(buf
), &sz
368 , diag_space
, sizeof(diag_space
), TTODATAV_SPACECOUNTS
);
371 /* ttodata didn't like PSK data */
372 ugh
= builddiag("PSK data malformed (%s): %s", ugh
, tok
);
376 chunk_t secret
= { buf
, sz
};
377 *psk
= chunk_clone(secret
);
384 typedef enum rsa_private_key_part_t rsa_private_key_part_t
;
386 enum rsa_private_key_part_t
{
387 RSA_PART_MODULUS
= 0,
388 RSA_PART_PUBLIC_EXPONENT
= 1,
389 RSA_PART_PRIVATE_EXPONENT
= 2,
392 RSA_PART_EXPONENT1
= 5,
393 RSA_PART_EXPONENT2
= 6,
394 RSA_PART_COEFFICIENT
= 7
397 const char *rsa_private_key_part_names
[] = {
409 * Parse fields of an RSA private key in BIND 8.2's representation
410 * consistiong of a braced list of keyword and value pairs in required order.
411 * Conversion into ASN.1 DER encoded PKCS#1 representation.
413 static err_t
process_rsa_secret(private_key_t
**key
)
415 chunk_t asn1_chunk
[countof(rsa_private_key_part_names
)];
417 u_char buf
[RSA_MAX_ENCODING_BYTES
]; /* limit on size of binary representation of key */
418 rsa_private_key_part_t part
, p
;
422 for (part
= RSA_PART_MODULUS
; part
<= RSA_PART_COEFFICIENT
; part
++)
424 chunk_t rsa_private_key_part
;
425 const char *keyword
= rsa_private_key_part_names
[part
];
429 ugh
= "premature end of RSA key";
432 if (!tokeqword(keyword
))
434 ugh
= builddiag("%s keyword not found where expected in RSA key"
438 if (!(shift() && (!tokeq(":") || shift()))) /* ignore optional ":" */
440 ugh
= "premature end of RSA key";
443 ugh
= ttodatav(tok
, flp
->cur
- tok
, 0, buf
, sizeof(buf
), &sz
,
444 diag_space
, sizeof(diag_space
), TTODATAV_SPACECOUNTS
);
447 ugh
= builddiag("RSA data malformed (%s): %s", ugh
, tok
);
451 rsa_private_key_part
= chunk_create(buf
, sz
);
452 asn1_chunk
[part
] = asn1_integer("c", rsa_private_key_part
);
453 len
+= asn1_chunk
[part
].len
;
456 /* We require an (indented) '}' and the end of the record.
457 * We break down the test so that the diagnostic will be more helpful.
458 * Some people don't seem to wish to indent the brace!
460 if (!shift() || !tokeq("}"))
462 ugh
= "malformed end of RSA private key -- indented '}' required";
467 ugh
= "malformed end of RSA private key -- unexpected token after '}'";
471 pkcs1_chunk
= asn1_wrap(ASN1_SEQUENCE
, "ccccccccc",
473 asn1_chunk
[RSA_PART_MODULUS
],
474 asn1_chunk
[RSA_PART_PUBLIC_EXPONENT
],
475 asn1_chunk
[RSA_PART_PRIVATE_EXPONENT
],
476 asn1_chunk
[RSA_PART_PRIME1
],
477 asn1_chunk
[RSA_PART_PRIME2
],
478 asn1_chunk
[RSA_PART_EXPONENT1
],
479 asn1_chunk
[RSA_PART_EXPONENT2
],
480 asn1_chunk
[RSA_PART_COEFFICIENT
]);
482 *key
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
, KEY_RSA
,
483 BUILD_BLOB_ASN1_DER
, pkcs1_chunk
,
485 free(pkcs1_chunk
.ptr
);
488 ugh
= "parsing of RSA private key failed";
492 /* clean up and return */
493 for (p
= RSA_PART_MODULUS
; p
< part
; p
++)
495 free(asn1_chunk
[p
].ptr
);
501 * process a key file protected with optional passphrase which can either be
502 * read from ipsec.secrets or prompted for by using whack
504 static err_t
process_keyfile(private_key_t
**key
, key_type_t type
, int whackfd
)
506 char filename
[BUF_LEN
];
509 memset(filename
,'\0', BUF_LEN
);
510 memset(pass
.secret
,'\0', sizeof(pass
.secret
));
514 /* we expect the filename of a PKCS#1 private key file */
516 if (*tok
== '"' || *tok
== '\'') /* quoted filename */
517 memcpy(filename
, tok
+1, flp
->cur
- tok
- 2);
519 memcpy(filename
, tok
, flp
->cur
- tok
);
523 /* we expect an appended passphrase or passphrase prompt*/
524 if (tokeqword("%prompt"))
526 if (pass
.fd
== NULL_FD
)
528 return "Private key file -- enter passphrase using 'ipsec secrets'";
534 char *passphrase
= tok
;
535 size_t len
= flp
->cur
- passphrase
;
537 if (*tok
== '"' || *tok
== '\'') /* quoted passphrase */
542 if (len
> PROMPT_PASS_LEN
)
544 return "Private key file -- passphrase exceeds 64 characters";
546 memcpy(pass
.secret
, passphrase
, len
);
550 return "Private key file -- unexpected token after passphrase";
553 *key
= load_private_key(filename
, &pass
, type
);
555 return key ? NULL
: "Private key file -- could not be loaded";
559 * Process xauth secret read from ipsec.secrets
561 static err_t
process_xauth(secret_t
*s
)
568 return "missing xauth user name";
569 if (*tok
== '"' || *tok
== '\'') /* quoted user name */
571 user_name
.ptr
= tok
+ 1;
572 user_name
.len
= flp
->cur
- tok
- 2;
577 user_name
.len
= flp
->cur
- tok
;
579 plog(" loaded xauth credentials of user '%.*s'"
582 s
->u
.xauth_secret
.user_name
= chunk_clone(user_name
);
585 return "missing xauth user password";
586 return process_psk_secret(&s
->u
.xauth_secret
.user_password
);
590 * Get XAUTH secret from chained secrets lists
591 * only one entry is currently supported
593 static bool xauth_get_secret(xauth_t
*xauth_secret
)
598 for (s
= secrets
; s
!= NULL
; s
= s
->next
)
600 if (s
->kind
== PPK_XAUTH
)
604 plog("found multiple xauth secrets - first selected");
609 *xauth_secret
= s
->u
.xauth_secret
;
617 * find a matching secret
619 static bool xauth_verify_secret(const xauth_peer_t
*peer
,
620 const xauth_t
*xauth_secret
)
625 for (s
= secrets
; s
!= NULL
; s
= s
->next
)
627 if (s
->kind
== PPK_XAUTH
)
629 if (!chunk_equals(xauth_secret
->user_name
, s
->u
.xauth_secret
.user_name
))
634 if (chunk_equals(xauth_secret
->user_password
, s
->u
.xauth_secret
.user_password
))
640 plog("xauth user '%.*s' %s"
641 , xauth_secret
->user_name
.len
, xauth_secret
->user_name
.ptr
642 , found?
"sent wrong password":"not found");
647 * the global xauth_module struct is defined here
649 xauth_module_t xauth_module
;
652 * Assign the default xauth functions to any null function pointers
654 void xauth_defaults(void)
656 if (xauth_module
.get_secret
== NULL
)
659 DBG_log("xauth module: using default get_secret() function")
661 xauth_module
.get_secret
= xauth_get_secret
;
663 if (xauth_module
.verify_secret
== NULL
)
666 DBG_log("xauth module: using default verify_secret() function")
668 xauth_module
.verify_secret
= xauth_verify_secret
;
673 * Process pin read from ipsec.secrets or prompted for it using whack
675 static err_t
process_pin(secret_t
*s
, int whackfd
)
678 const char *pin_status
= "no pin";
682 /* looking for the smartcard keyword */
683 if (!shift() || strncmp(tok
, SCX_TOKEN
, strlen(SCX_TOKEN
)) != 0)
684 return "PIN keyword must be followed by %smartcard<reader>:<id>";
686 sc
= scx_add(scx_parse_number_slot_id(tok
+ strlen(SCX_TOKEN
)));
689 if (sc
->pin
.ptr
!= NULL
)
691 scx_release_context(sc
);
692 scx_free_pin(&sc
->pin
);
697 return "PIN statement must be terminated either by <pin code>, %pinpad or %prompt";
699 if (tokeqword("%prompt"))
702 /* if whackfd exists, whack will be used to prompt for a pin */
703 if (whackfd
!= NULL_FD
)
704 pin_status
= scx_get_pin(sc
, whackfd
) ?
"valid pin" : "invalid pin";
706 pin_status
= "pin entry via prompt";
708 else if (tokeqword("%pinpad"))
710 chunk_t empty_pin
= { "", 0 };
714 /* pin will be entered via pin pad during verification */
715 sc
->pin
= chunk_clone(empty_pin
);
718 pin_status
= "pin entry via pad";
719 if (pkcs11_keep_state
)
726 /* we read the pin directly from ipsec.secrets */
727 err_t ugh
= process_psk_secret(&sc
->pin
);
731 pin_status
= scx_verify_pin(sc
) ?
"valid PIN" : "invalid PIN";
738 snprintf(buf
, BUF_LEN
, "any slot");
740 snprintf(buf
, BUF_LEN
, "slot: %lu", sc
->slot
);
742 plog(" %s for #%d (%s, id: %s)"
743 , pin_status
, sc
->number
, scx_print_slot(sc
, ""), sc
->id
);
746 plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
751 static void log_psk(secret_t
*s
)
755 id_list_t
*id_list
= s
->ids
;
759 n
= snprintf(buf
, BUF_LEN
, "%%any");
765 n
+= idtoa(&id_list
->id
, buf
+ n
, BUF_LEN
- n
);
771 else if (n
< BUF_LEN
- 1)
773 n
+= snprintf(buf
+ n
, BUF_LEN
- n
, " ");
775 id_list
= id_list
->next
;
779 plog(" loaded shared key for %.*s", n
, buf
);
782 static void process_secret(secret_t
*s
, int whackfd
)
786 s
->kind
= PPK_PSK
; /* default */
787 if (*tok
== '"' || *tok
== '\'')
789 /* old PSK format: just a string */
791 ugh
= process_psk_secret(&s
->u
.preshared_secret
);
793 else if (tokeqword("psk"))
795 /* preshared key: quoted string or ttodata format */
797 ugh
= !shift()?
"unexpected end of record in PSK"
798 : process_psk_secret(&s
->u
.preshared_secret
);
800 else if (tokeqword("rsa"))
802 /* RSA key: the fun begins.
803 * A braced list of keyword and value pairs.
805 s
->kind
= PPK_PUBKEY
;
808 ugh
= "bad RSA key syntax";
812 ugh
= process_rsa_secret(&s
->u
.private_key
);
816 ugh
= process_keyfile(&s
->u
.private_key
, KEY_RSA
, whackfd
);
819 else if (tokeqword("ecdsa"))
821 s
->kind
= PPK_PUBKEY
;
824 ugh
= "bad ECDSA key syntax";
828 ugh
= process_keyfile(&s
->u
.private_key
, KEY_ECDSA
, whackfd
);
831 else if (tokeqword("xauth"))
833 ugh
= process_xauth(s
);
835 else if (tokeqword("pin"))
837 ugh
= process_pin(s
, whackfd
);
841 ugh
= builddiag("unrecognized key format: %s", tok
);
846 loglog(RC_LOG_SERIOUS
, "\"%s\" line %d: %s"
847 , flp
->filename
, flp
->lino
, ugh
);
850 else if (flushline("expected record boundary in key"))
852 /* gauntlet has been run: install new secret */
853 lock_certs_and_keys("process_secret");
856 unlock_certs_and_keys("process_secrets");
860 static void process_secrets_file(const char *file_pat
, int whackfd
); /* forward declaration */
862 static void process_secret_records(int whackfd
)
864 /* read records from ipsec.secrets and load them into our table */
867 (void)flushline(NULL
); /* silently ditch leftovers, if any */
868 if (flp
->bdry
== B_file
)
872 flp
->bdry
= B_none
; /* eat the Record Boundary */
873 (void)shift(); /* get real first token */
875 if (tokeqword("include"))
877 /* an include directive */
878 char fn
[MAX_TOK_LEN
]; /* space for filename (I hope) */
880 char *end_prefix
= strrchr(flp
->filename
, '/');
884 loglog(RC_LOG_SERIOUS
, "\"%s\" line %d: unexpected end of include directive"
885 , flp
->filename
, flp
->lino
);
886 continue; /* abandon this record */
889 /* if path is relative and including file's pathname has
890 * a non-empty dirname, prefix this path with that dirname.
892 if (tok
[0] != '/' && end_prefix
!= NULL
)
894 size_t pl
= end_prefix
- flp
->filename
+ 1;
896 /* "clamp" length to prevent problems now;
897 * will be rediscovered and reported later.
903 memcpy(fn
, flp
->filename
, pl
);
906 if (flp
->cur
- tok
>= &fn
[sizeof(fn
)] - p
)
908 loglog(RC_LOG_SERIOUS
, "\"%s\" line %d: include pathname too long"
909 , flp
->filename
, flp
->lino
);
910 continue; /* abandon this record */
913 (void) shift(); /* move to Record Boundary, we hope */
914 if (flushline("ignoring malformed INCLUDE -- expected Record Boundary after filename"))
916 process_secrets_file(fn
, whackfd
);
917 tok
= NULL
; /* correct, but probably redundant */
922 /* expecting a list of indices and then the key info */
923 secret_t
*s
= malloc_thing(secret_t
);
927 s
->kind
= PPK_PSK
; /* default */
928 s
->u
.preshared_secret
= chunk_empty
;
933 if (tok
[0] == '"' || tok
[0] == '\'')
936 process_secret(s
, whackfd
);
942 shift(); /* discard explicit separator */
943 process_secret(s
, whackfd
);
949 * See RFC2407 IPsec Domain of Interpretation 4.6.2
957 id
.kind
= ID_IPV4_ADDR
;
958 ugh
= anyaddr(AF_INET
, &id
.ip_addr
);
960 else if (tokeq("%any6"))
963 id
.kind
= ID_IPV6_ADDR
;
964 ugh
= anyaddr(AF_INET6
, &id
.ip_addr
);
968 ugh
= atoid(tok
, &id
, FALSE
);
973 loglog(RC_LOG_SERIOUS
974 , "ERROR \"%s\" line %d: index \"%s\" %s"
975 , flp
->filename
, flp
->lino
, tok
, ugh
);
979 id_list_t
*i
= malloc_thing(id_list_t
);
982 unshare_id_content(&i
->id
);
985 /* DBG_log("id type %d: %s %.*s", i->kind, ip_str(&i->ip_addr), (int)i->name.len, i->name.ptr); */
989 /* unexpected Record Boundary or EOF */
990 loglog(RC_LOG_SERIOUS
, "\"%s\" line %d: unexpected end of id list"
991 , flp
->filename
, flp
->lino
);
1000 static int globugh(const char *epath
, int eerrno
)
1002 log_errno_routine(eerrno
, "problem with secrets file \"%s\"", epath
);
1003 return 1; /* stop glob */
1006 static void process_secrets_file(const char *file_pat
, int whackfd
)
1008 struct file_lex_position pos
;
1012 pos
.depth
= flp
== NULL?
0 : flp
->depth
+ 1;
1016 loglog(RC_LOG_SERIOUS
, "preshared secrets file \"%s\" nested too deeply", file_pat
);
1022 int r
= glob(file_pat
, GLOB_ERR
, globugh
, &globbuf
);
1029 loglog(RC_LOG_SERIOUS
, "out of space processing secrets filename \"%s\"", file_pat
);
1032 break; /* already logged */
1034 loglog(RC_LOG_SERIOUS
, "no secrets filename matched \"%s\"", file_pat
);
1037 loglog(RC_LOG_SERIOUS
, "unknown glob error %d", r
);
1045 /* for each file... */
1046 for (fnp
= globbuf
.gl_pathv
; *fnp
!= NULL
; fnp
++)
1048 if (lexopen(&pos
, *fnp
, FALSE
))
1050 plog("loading secrets from \"%s\"", *fnp
);
1051 (void) flushline("file starts with indentation (continuation notation)");
1052 process_secret_records(whackfd
);
1060 void free_preshared_secrets(void)
1062 lock_certs_and_keys("free_preshared_secrets");
1064 if (secrets
!= NULL
)
1068 plog("forgetting secrets");
1070 for (s
= secrets
; s
!= NULL
; s
= ns
)
1074 ns
= s
->next
; /* grab before freeing s */
1075 for (i
= s
->ids
; i
!= NULL
; i
= ni
)
1077 ni
= i
->next
; /* grab before freeing i */
1078 free_id_content(&i
->id
);
1084 free(s
->u
.preshared_secret
.ptr
);
1087 DESTROY_IF(s
->u
.private_key
);
1090 free(s
->u
.xauth_secret
.user_name
.ptr
);
1091 free(s
->u
.xauth_secret
.user_password
.ptr
);
1094 scx_release(s
->u
.smartcard
);
1104 unlock_certs_and_keys("free_preshard_secrets");
1107 void load_preshared_secrets(int whackfd
)
1109 free_preshared_secrets();
1110 (void) process_secrets_file(shared_secrets_file
, whackfd
);
1113 /* public key machinery
1114 * Note: caller must set dns_auth_level.
1117 pubkey_t
* public_key_from_rsa(public_key_t
*key
)
1119 pubkey_t
*p
= malloc_thing(pubkey_t
);
1122 p
->id
= empty_id
; /* don't know, doesn't matter */
1123 p
->issuer
= chunk_empty
;
1124 p
->serial
= chunk_empty
;
1125 p
->public_key
= key
;
1127 /* note that we return a 1 reference count upon creation:
1128 * invariant: recount > 0.
1131 time(&p
->installed_time
);
1135 /* Free a public key record.
1136 * As a convenience, this returns a pointer to next.
1138 pubkey_list_t
* free_public_keyentry(pubkey_list_t
*p
)
1140 pubkey_list_t
*nxt
= p
->next
;
1144 unreference_key(&p
->key
);
1150 void free_public_keys(pubkey_list_t
**keys
)
1152 while (*keys
!= NULL
)
1154 *keys
= free_public_keyentry(*keys
);
1158 /* root of chained public key list */
1160 pubkey_list_t
*pubkeys
= NULL
; /* keys from ipsec.conf */
1162 void free_remembered_public_keys(void)
1164 free_public_keys(&pubkeys
);
1168 * Transfer public keys from *keys list to front of pubkeys list
1170 void transfer_to_public_keys(struct gw_info
*gateways_from_dns
1172 , pubkey_list_t
**keys
1173 #endif /* USE_KEYRR */
1177 struct gw_info
*gwp
;
1179 for (gwp
= gateways_from_dns
; gwp
!= NULL
; gwp
= gwp
->next
)
1181 pubkey_list_t
*pl
= malloc_thing(pubkey_list_t
);
1183 pl
->key
= gwp
->key
; /* note: this is a transfer */
1184 gwp
->key
= NULL
; /* really, it is! */
1192 pubkey_list_t
**pp
= keys
;
1202 #endif /* USE_KEYRR */
1206 static void install_public_key(pubkey_t
*pk
, pubkey_list_t
**head
)
1208 pubkey_list_t
*p
= malloc_thing(pubkey_list_t
);
1210 unshare_id_content(&pk
->id
);
1212 /* copy issuer dn */
1213 pk
->issuer
= chunk_clone(pk
->issuer
);
1215 /* copy serial number */
1216 pk
->serial
= chunk_clone(pk
->serial
);
1218 /* store the time the public key was installed */
1219 time(&pk
->installed_time
);
1221 /* install new key at front */
1222 p
->key
= reference_key(pk
);
1227 void delete_public_keys(const struct id
*id
, key_type_t type
,
1228 chunk_t issuer
, chunk_t serial
)
1230 pubkey_list_t
**pp
, *p
;
1234 for (pp
= &pubkeys
; (p
= *pp
) != NULL
; )
1237 pk_type
= pk
->public_key
->get_type(pk
->public_key
);
1239 if (same_id(id
, &pk
->id
) && pk_type
== type
1240 && (issuer
.ptr
== NULL
|| pk
->issuer
.ptr
== NULL
1241 || same_dn(issuer
, pk
->issuer
))
1242 && same_serial(serial
, pk
->serial
))
1244 *pp
= free_public_keyentry(p
);
1253 pubkey_t
* reference_key(pubkey_t
*pk
)
1260 unreference_key(pubkey_t
**pkp
)
1262 pubkey_t
*pk
= *pkp
;
1271 DBG(DBG_CONTROLMORE
,
1272 idtoa(&pk
->id
, b
, sizeof(b
));
1273 DBG_log("unreference key: %p %s cnt %d--", pk
, b
, pk
->refcnt
)
1276 /* cancel out the pointer */
1279 passert(pk
->refcnt
!= 0);
1281 if (pk
->refcnt
== 0)
1283 free_public_key(pk
);
1287 bool add_public_key(const struct id
*id
, enum dns_auth_level dns_auth_level
,
1288 enum pubkey_alg alg
, chunk_t rfc3110_key
,
1289 pubkey_list_t
**head
)
1291 public_key_t
*key
= NULL
;
1294 /* first: algorithm-specific decoding of key chunk */
1297 case PUBKEY_ALG_RSA
:
1298 key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
, KEY_RSA
,
1299 BUILD_BLOB_RFC_3110
, rfc3110_key
,
1310 pk
= malloc_thing(pubkey_t
);
1312 pk
->public_key
= key
;
1314 pk
->dns_auth_level
= dns_auth_level
;
1315 pk
->until_time
= UNDEFINED_TIME
;
1316 pk
->issuer
= chunk_empty
;
1317 pk
->serial
= chunk_empty
;
1318 install_public_key(pk
, head
);
1322 /* extract id and public key from x.509 certificate and
1323 * insert it into a pubkeyrec
1325 void add_x509_public_key(x509cert_t
*cert
, time_t until
,
1326 enum dns_auth_level dns_auth_level
)
1332 /* ID type: ID_DER_ASN1_DN (X.509 subject field) */
1333 pk
= malloc_thing(pubkey_t
);
1335 pk
->public_key
= cert
->public_key
->get_ref(cert
->public_key
);
1336 pk
->id
.kind
= ID_DER_ASN1_DN
;
1337 pk
->id
.name
= cert
->subject
;
1338 pk
->dns_auth_level
= dns_auth_level
;
1339 pk
->until_time
= until
;
1340 pk
->issuer
= cert
->issuer
;
1341 pk
->serial
= cert
->serialNumber
;
1342 pk_type
= pk
->public_key
->get_type(pk
->public_key
);
1343 delete_public_keys(&pk
->id
, pk_type
, pk
->issuer
, pk
->serial
);
1344 install_public_key(pk
, &pubkeys
);
1346 gn
= cert
->subjectAltName
;
1348 while (gn
!= NULL
) /* insert all subjectAltNames */
1350 struct id id
= empty_id
;
1353 if (id
.kind
!= ID_ANY
)
1355 pk
= malloc_thing(pubkey_t
);
1357 pk
->public_key
= cert
->public_key
->get_ref(cert
->public_key
);
1359 pk
->dns_auth_level
= dns_auth_level
;
1360 pk
->until_time
= until
;
1361 pk
->issuer
= cert
->issuer
;
1362 pk
->serial
= cert
->serialNumber
;
1363 delete_public_keys(&pk
->id
, pk_type
, pk
->issuer
, pk
->serial
);
1364 install_public_key(pk
, &pubkeys
);
1370 /* extract id and public key from OpenPGP certificate and
1371 * insert it into a pubkeyrec
1373 void add_pgp_public_key(pgpcert_t
*cert
, time_t until
,
1374 enum dns_auth_level dns_auth_level
)
1379 pk
= malloc_thing(pubkey_t
);
1381 pk
->public_key
= cert
->public_key
->get_ref(cert
->public_key
);
1382 pk
->id
.kind
= ID_KEY_ID
;
1383 pk
->id
.name
= cert
->fingerprint
->get_encoding(cert
->fingerprint
);
1384 pk
->dns_auth_level
= dns_auth_level
;
1385 pk
->until_time
= until
;
1386 pk_type
= pk
->public_key
->get_type(pk
->public_key
);
1387 delete_public_keys(&pk
->id
, pk_type
, chunk_empty
, chunk_empty
);
1388 install_public_key(pk
, &pubkeys
);
1391 /* when a X.509 certificate gets revoked, all instances of
1392 * the corresponding public key must be removed
1394 void remove_x509_public_key(const x509cert_t
*cert
)
1396 public_key_t
*revoked_key
= cert
->public_key
;
1397 pubkey_list_t
*p
, **pp
;
1404 if (revoked_key
->equals(revoked_key
, p
->key
->public_key
))
1406 /* remove p from list and free memory */
1407 *pp
= free_public_keyentry(p
);
1408 loglog(RC_LOG_SERIOUS
, "invalid public key deleted");
1419 * list all public keys in the chained list
1421 void list_public_keys(bool utc
)
1423 pubkey_list_t
*p
= pubkeys
;
1427 whack_log(RC_COMMENT
, " ");
1428 whack_log(RC_COMMENT
, "List of Public Keys:");
1429 whack_log(RC_COMMENT
, " ");
1434 pubkey_t
*key
= p
->key
;
1435 public_key_t
*public = key
->public_key
;
1436 identification_t
*keyid
= public->get_id(public, ID_PUBKEY_INFO_SHA1
);
1439 idtoa(&key
->id
, buf
, BUF_LEN
);
1440 whack_log(RC_COMMENT
,"%T, '%s'", &key
->installed_time
, utc
, buf
);
1441 whack_log(RC_COMMENT
, " pubkey: %N %4d bits, until %T %s",
1442 key_type_names
, public->get_type(public),
1443 public->get_keysize(public) * BITS_PER_BYTE
,
1444 &key
->until_time
, utc
,
1445 check_expiry(key
->until_time
, PUBKEY_WARNING_INTERVAL
, TRUE
));
1446 whack_log(RC_COMMENT
," keyid: %Y", keyid
);
1447 if (key
->issuer
.len
> 0)
1449 dntoa(buf
, BUF_LEN
, key
->issuer
);
1450 whack_log(RC_COMMENT
," issuer: '%s'", buf
);
1452 if (key
->serial
.len
> 0)
1454 datatot(key
->serial
.ptr
, key
->serial
.len
, ':'
1456 whack_log(RC_COMMENT
," serial: %s", buf
);