chiark / gitweb /
Merge branch 'mdw/multi-priv'
authorMark Wooding <mdw@distorted.org.uk>
Tue, 18 Sep 2012 02:32:53 +0000 (03:32 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Tue, 18 Sep 2012 02:32:53 +0000 (03:32 +0100)
* mdw/multi-priv:
  server/tests.at, t/keyring-*: New tests for key management.
  Allow different peer associations to use different private keys.
  server: Use the new kdata system.
  server/{keymgmt.c,tripe.h}: Unify public and private key handling.
  server/keyexch.c: Prefix crypto-details trace messages correctly.
  server/{keymgmt.c,tripe-admin.5.in}: Improve key-management errors.
  admin.c (a_format): New function formats token sequences to strings.

Conflicts:
server/tests.at
server/tripe.h

1  2 
server/keyexch.c
server/keyset.c
server/tests.at
server/tripe.h

@@@ -1358,15 -1383,19 +1477,20 @@@ newkeys
  
  int kx_init(keyexch *kx, peer *p, keyset **ks, unsigned f)
  {
+   if ((kx->kpriv = km_findpriv(p_privtag(p))) == 0) goto fail_0;
+   if ((kx->kpub = km_findpub(p_tag(p))) == 0) goto fail_1;
+   if (!group_samep(kx->kpriv->g, kx->kpub->g)) {
+     a_warn("KX", "?PEER", kx->p, "group-mismatch",
+          "local-private-key", "%s", p_privtag(p),
+          "peer-public-key", "%s", p_tag(p),
+          A_END);
+     goto fail_2;
+   }
    kx->ks = ks;
    kx->p = p;
-   kx->kpub = G_CREATE(gg);
-   if (km_getpubkey(p_tag(p), kx->kpub, &kx->texp_kpub)) {
-     G_DESTROY(gg, kx->kpub);
-     return (-1);
-   }
    kx->f = KXF_DEAD | KXF_PUBKEY | f;
 +  rs_reset(&kx->rs);
    if (!(kx->f & KXF_CORK)) {
      start(kx, time(0));
      resend(kx);
diff --cc server/keyset.c
Simple merge
diff --cc server/tests.at
@@@ -439,44 -424,143 +439,181 @@@ WITH_3TRIPES([alice], [bob], [carol], [
  AT_CLEANUP
  
  ###--------------------------------------------------------------------------
 +### Adverse communication.
 +
 +AT_SETUP([server retry])
 +AT_KEYWORDS([backoff])
 +export TRIPE_SLIPIF=USLIP
 +
 +for i in alice bob; do (mkdir $i; cd $i; SETUPDIR([beta])); done
 +
 +WITH_2TRIPES([alice], [bob], [-nslip], [-talice], [-tbob], [
 +
 +  ## Set up the evil proxy.
 +  alicemitm=24516 bobmitm=14016
 +  MITM -kalice/keyring.pub >mitm.out 2>mitm.err \
 +    peer:alice:$alicemitm:127.0.0.1:$(cat alice/port) \
 +    peer:bob:$bobmitm:127.0.0.1:$(cat bob/port) \
 +    filt:drop:5 filt:send& mitmpid=$!
 +  strace -omitm.trace -p$mitmpid& mitmtrace=$!
 +  trap 'kill $mitmpid $mitmtrace; exit 127' EXIT INT QUIT TERM HUP
 +
 +  ## Try to establish keys anyway.
 +  AWAIT_KXDONE([alice], [alice], [bob], [bob], [
 +    AT_CHECK([TRIPECTL -dalice ADD -cork bob   INET 127.0.0.1 $alicemitm])
 +    AT_CHECK([TRIPECTL -dbob   ADD       alice INET 127.0.0.1 $bobmitm])
 +  ])
 +
 +  ## Check pinging.
 +  COMMS_EPING([alice], [alice], [bob], [bob], [10])
 +  COMMS_EPING([bob], [bob], [alice], [alice], [10])
 +
 +  ## Tear down the MITM proxy.
 +  kill $mitmpid
 +  wait $mitmpid
 +  wait $mitmtrace
 +])
 +
 +AT_CLEANUP
 +
 +###--------------------------------------------------------------------------
+ ### Key management.
+ AT_SETUP([server key-management])
+ AT_KEYWORDS([keymgmt])
+ export TRIPE_SLIPIF=USLIP
+ ## Determine all of the nets and the principals.
+ princs=""
+ nets=" "
+ while read princ pnets; do
+   princs="$princs $princ"
+   for n in $pnets; do
+     case " $nets " in *" $n "*) ;; *) nets="$nets$n " ;; esac
+   done
+ done <<PRINC
+ alice alpha   beta
+ bob   alpha   beta
+ carol beta
+ PRINC
+ ## Build the master keyring.  All key tags here are of the form PRINC/NET.
+ for n in $nets; do
+   key -k$abs_top_srcdir/t/keyring-$n extract keyring-$n $princs
+   for p in $princs; do key -kkeyring-$n tag $p $p/$n; done
+   key merge keyring-$n
+   rm keyring-$n
+ done
+ key extract -f-secret keyring.pub
+ ## Set up the principals' directories.
+ for p in $princs; do
+   mkdir $p
+   cp keyring keyring.pub $p/
+ done
+ WITH_3TRIPES([alice], [bob], [carol], [-nslip -Tmx],
+       [-talice/alpha], [-tbob/alpha], [-tcarol/beta], [
+   ## Establish this little merry-go-round.
+   ESTABLISH([alice], [alice], [-key alice/alpha],
+       [bob], [bob], [-key bob/alpha])
+   ESTABLISH([alice], [alice], [-key alice/beta],
+       [carol], [carol], [-priv alice/beta -key carol/beta])
+   ESTABLISH([bob], [bob], [-key bob/beta],
+       [carol], [carol], [-priv bob/beta -key carol/beta])
+   ## Tweak Bob's alpha key.
+   for p in $princs; do
+     TRIPECTL -d$p WARN test COMMENT tweak bob/alpha
+   done
+   key -k$abs_top_srcdir/t/keyring-alpha extract keyring-bob-new bob-new
+   key merge keyring-bob-new
+   key tag -r bob-new bob/alpha
+   key extract -f-secret keyring.pub
+   for p in alice bob; do cp keyring keyring.pub $p/; done
+   ## Kick the peers to see whether they update.
+   AWAIT_KXDONE([alice], [alice], [bob], [bob], [
+     TRIPECTL -dalice RELOAD
+     TRIPECTL -dbob RELOAD
+     TRIPECTL -dalice FORCEKX bob
+     TRIPECTL -dbob FORCEKX alice
+   ])
+   COMMS_EPING([alice], [alice], [bob], [bob])
+   COMMS_EPING([bob], [bob], [alice], [alice])
+   ## Update the beta ring.
+   key merge $abs_top_srcdir/t/keyring-beta-new
+   for p in $princs; do key tag -r $p $p/beta; done
+   key extract -f-secret keyring.pub
+   ## Update alice's and carol's private keys, bob's public.  This should be
+   ## insufficient for them to switch, but the results could be interesting.
+   for p in $princs; do
+     TRIPECTL -d$p WARN test COMMENT tweak beta step 1
+   done
+   for p in alice carol; do cp keyring $p/; done
+   cp keyring.pub bob/
+   for p in $princs; do TRIPECTL -d$p RELOAD; done
+   AT_DATA([algs-alpha], [dnl
+ kx-group=ec kx-group-order-bits=256 kx-group-elt-bits=512
+ hash=rmd160 mgf=rmd160-mgf hash-sz=20
+ cipher=blowfish-cbc cipher-keysz=20 cipher-blksz=8
+ cipher-data-limit=67108864
+ mac=rmd160-hmac mac-keysz=20 mac-tagsz=10
+ ])
+   AT_DATA([algs-beta-old], [dnl
+ kx-group=prime kx-group-order-bits=160 kx-group-elt-bits=1023
+ hash=rmd160 mgf=rmd160-mgf hash-sz=20
+ cipher=blowfish-cbc cipher-keysz=20 cipher-blksz=8
+ cipher-data-limit=67108864
+ mac=rmd160-hmac mac-keysz=20 mac-tagsz=10
+ ])
+   AT_DATA([algs-beta-new], [dnl
+ kx-group=ec kx-group-order-bits=161 kx-group-elt-bits=320
+ hash=rmd160 mgf=rmd160-mgf hash-sz=20
+ cipher=blowfish-cbc cipher-keysz=20 cipher-blksz=8
+ cipher-data-limit=67108864
+ mac=rmd160-hmac mac-keysz=20 mac-tagsz=10
+ ])
+   cp algs-alpha expout;    AT_CHECK([TRIPECTL -dalice ALGS],,       [expout])
+   cp algs-beta-old expout; AT_CHECK([TRIPECTL -dalice ALGS carol],, [expout])
+   cp algs-beta-old expout; AT_CHECK([TRIPECTL -dbob   ALGS carol],, [expout])
+   cp algs-beta-new expout; AT_CHECK([TRIPECTL -dcarol ALGS],,       [expout])
+   cp algs-beta-old expout; AT_CHECK([TRIPECTL -dcarol ALGS alice],, [expout])
+   ## Now copy the full keys.  We expect this to provoke key exchange.
+   for p in $princs; do
+     TRIPECTL -d$p WARN test COMMENT tweak beta step 2
+   done
+   for p in $princs; do cp keyring keyring.pub $p/; done
+   AWAIT_KXDONE([alice], [alice], [carol], [carol], [
+     TRIPECTL -dalice RELOAD
+     AWAIT_KXDONE([bob], [bob], [carol], [carol], [
+       TRIPECTL -dbob RELOAD
+       TRIPECTL -dcarol RELOAD
+     ])
+   ])
+   cp algs-alpha expout;    AT_CHECK([TRIPECTL -dalice ALGS],,       [expout])
+   cp algs-beta-new expout; AT_CHECK([TRIPECTL -dalice ALGS carol],, [expout])
+   cp algs-beta-new expout; AT_CHECK([TRIPECTL -dbob   ALGS carol],, [expout])
+   cp algs-beta-new expout; AT_CHECK([TRIPECTL -dcarol ALGS],,       [expout])
+ ])
+ AT_CLEANUP
+ ###--------------------------------------------------------------------------
  ### Services.
  
  AT_SETUP([server services])
diff --cc server/tripe.h
@@@ -279,9 -281,6 +299,7 @@@ typedef struct keyexch 
    unsigned f;                         /* Various useful flags */
    unsigned s;                         /* Current state in exchange */
    sel_timer t;                                /* Timer for next exchange */
-   ge *kpub;                           /* Peer's public key */
-   time_t texp_kpub;                   /* Expiry time for public key */
 +  retry rs;                           /* Retry state */
    mp *alpha;                          /* My temporary secret */
    ge *c;                              /* My challenge */
    ge *rx;                             /* The expected response */