/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to plugins.d/mandos-client.c

  • Committer: Teddy Hogeborn
  • Date: 2018-08-15 09:26:02 UTC
  • Revision ID: teddy@recompile.se-20180815092602-xoyb5s6gf8376i7u
mandos-client: Set system clock if necessary

* plugins.d/mandos-client.c (init_gpgme/import_key): If the system
  clock is not set, or set to january 1970, set the system clock to
  the more plausible value that is the mtime of the key file.  This is
  required by GnuPG to be able to import the keys.  (We can't pass the
  --ignore-time-conflict or the --ignore-valid-from options though
  GPGME.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 * "browse_callback", and parts of "main".
10
10
 * 
11
11
 * Everything else is
12
 
 * Copyright © 2008-2019 Teddy Hogeborn
13
 
 * Copyright © 2008-2019 Björn Påhlsson
 
12
 * Copyright © 2008-2018 Teddy Hogeborn
 
13
 * Copyright © 2008-2018 Björn Påhlsson
14
14
 * 
15
15
 * This file is part of Mandos.
16
16
 * 
123
123
                                   gnutls_*
124
124
                                   init_gnutls_session(),
125
125
                                   GNUTLS_* */
126
 
#if GNUTLS_VERSION_NUMBER < 0x030600
127
126
#include <gnutls/openpgp.h>
128
127
                         /* gnutls_certificate_set_openpgp_key_file(),
129
128
                            GNUTLS_OPENPGP_FMT_BASE64 */
130
 
#elif GNUTLS_VERSION_NUMBER >= 0x030606
131
 
#include <gnutls/x509.h>        /* gnutls_pkcs_encrypt_flags_t,
132
 
                                 GNUTLS_PKCS_PLAIN,
133
 
                                 GNUTLS_PKCS_NULL_PASSWORD */
134
 
#endif
135
129
 
136
130
/* GPGME */
137
131
#include <gpgme.h>              /* All GPGME types, constants and
145
139
#define PATHDIR "/conf/conf.d/mandos"
146
140
#define SECKEY "seckey.txt"
147
141
#define PUBKEY "pubkey.txt"
148
 
#define TLS_PRIVKEY "tls-privkey.pem"
149
 
#define TLS_PUBKEY "tls-pubkey.pem"
150
142
#define HOOKDIR "/lib/mandos/network-hooks.d"
151
143
 
152
144
bool debug = false;
707
699
                              const char *dhparamsfilename,
708
700
                              mandos_context *mc){
709
701
  int ret;
 
702
  unsigned int uret;
710
703
  
711
704
  if(debug){
712
705
    fprintf_plus(stderr, "Initializing GnuTLS\n");
729
722
  }
730
723
  
731
724
  if(debug){
732
 
    fprintf_plus(stderr, "Attempting to use public key %s and"
733
 
                 " private key %s as GnuTLS credentials\n",
 
725
    fprintf_plus(stderr, "Attempting to use OpenPGP public key %s and"
 
726
                 " secret key %s as GnuTLS credentials\n",
734
727
                 pubkeyfilename,
735
728
                 seckeyfilename);
736
729
  }
737
730
  
738
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
739
 
  ret = gnutls_certificate_set_rawpk_key_file
740
 
    (mc->cred, pubkeyfilename, seckeyfilename,
741
 
     GNUTLS_X509_FMT_PEM,       /* format */
742
 
     NULL,                      /* pass */
743
 
     /* key_usage */
744
 
     GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
745
 
     NULL,                      /* names */
746
 
     0,                         /* names_length */
747
 
     /* privkey_flags */
748
 
     GNUTLS_PKCS_PLAIN | GNUTLS_PKCS_NULL_PASSWORD,
749
 
     0);                        /* pkcs11_flags */
750
 
#elif GNUTLS_VERSION_NUMBER < 0x030600
751
731
  ret = gnutls_certificate_set_openpgp_key_file
752
732
    (mc->cred, pubkeyfilename, seckeyfilename,
753
733
     GNUTLS_OPENPGP_FMT_BASE64);
754
 
#else
755
 
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
756
 
#endif
757
734
  if(ret != GNUTLS_E_SUCCESS){
758
735
    fprintf_plus(stderr,
759
 
                 "Error[%d] while reading the key pair ('%s',"
 
736
                 "Error[%d] while reading the OpenPGP key pair ('%s',"
760
737
                 " '%s')\n", ret, pubkeyfilename, seckeyfilename);
761
738
    fprintf_plus(stderr, "The GnuTLS error is: %s\n",
762
739
                 safer_gnutls_strerror(ret));
833
810
  }
834
811
  if(dhparamsfilename == NULL){
835
812
    if(mc->dh_bits == 0){
836
 
#if GNUTLS_VERSION_NUMBER < 0x030600
837
813
      /* Find out the optimal number of DH bits */
838
814
      /* Try to read the private key file */
839
815
      gnutls_datum_t buffer = { .data = NULL, .size = 0 };
919
895
          }
920
896
        }
921
897
      }
922
 
      unsigned int uret = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param);
 
898
      uret = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param);
923
899
      if(uret != 0){
924
900
        mc->dh_bits = uret;
925
901
        if(debug){
937
913
                     safer_gnutls_strerror(ret));
938
914
        goto globalfail;
939
915
      }
940
 
#endif
941
 
    } else {                    /* dh_bits != 0 */
942
 
      if(debug){
943
 
        fprintf_plus(stderr, "DH bits explicitly set to %u\n",
944
 
                     mc->dh_bits);
945
 
      }
946
 
      ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
947
 
      if(ret != GNUTLS_E_SUCCESS){
948
 
        fprintf_plus(stderr, "Error in GnuTLS prime generation (%u"
949
 
                     " bits): %s\n", mc->dh_bits,
950
 
                     safer_gnutls_strerror(ret));
951
 
        goto globalfail;
952
 
      }
953
 
      gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
 
916
    } else if(debug){
 
917
      fprintf_plus(stderr, "DH bits explicitly set to %u\n",
 
918
                   mc->dh_bits);
 
919
    }
 
920
    ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
 
921
    if(ret != GNUTLS_E_SUCCESS){
 
922
      fprintf_plus(stderr, "Error in GnuTLS prime generation (%u"
 
923
                   " bits): %s\n", mc->dh_bits,
 
924
                   safer_gnutls_strerror(ret));
 
925
      goto globalfail;
954
926
    }
955
927
  }
 
928
  gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
956
929
  
957
930
  return 0;
958
931
  
969
942
  int ret;
970
943
  /* GnuTLS session creation */
971
944
  do {
972
 
    ret = gnutls_init(session, (GNUTLS_SERVER
973
 
#if GNUTLS_VERSION_NUMBER >= 0x030506
974
 
                                | GNUTLS_NO_TICKETS
975
 
#endif
976
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
977
 
                                | GNUTLS_ENABLE_RAWPK
978
 
#endif
979
 
                                ));
 
945
    ret = gnutls_init(session, GNUTLS_SERVER);
980
946
    if(quit_now){
981
947
      return -1;
982
948
    }
2461
2427
 
2462
2428
int main(int argc, char *argv[]){
2463
2429
  mandos_context mc = { .server = NULL, .dh_bits = 0,
2464
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2465
 
                        .priority = "SECURE128:!CTYPE-X.509"
2466
 
                        ":+CTYPE-RAWPK:!RSA:!VERS-ALL:+VERS-TLS1.3"
2467
 
                        ":%PROFILE_ULTRA",
2468
 
#elif GNUTLS_VERSION_NUMBER < 0x030600
2469
2430
                        .priority = "SECURE256:!CTYPE-X.509"
2470
2431
                        ":+CTYPE-OPENPGP:!RSA:+SIGN-DSA-SHA256",
2471
 
#else
2472
 
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
2473
 
#endif
2474
2432
                        .current_server = NULL, .interfaces = NULL,
2475
2433
                        .interfaces_size = 0 };
2476
2434
  AvahiSServiceBrowser *sb = NULL;
2487
2445
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
2488
2446
  const char *seckey = PATHDIR "/" SECKEY;
2489
2447
  const char *pubkey = PATHDIR "/" PUBKEY;
2490
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2491
 
  const char *tls_privkey = PATHDIR "/" TLS_PRIVKEY;
2492
 
  const char *tls_pubkey = PATHDIR "/" TLS_PUBKEY;
2493
 
#endif
2494
2448
  const char *dh_params_file = NULL;
2495
2449
  char *interfaces_hooks = NULL;
2496
2450
  
2544
2498
      { .name = "pubkey", .key = 'p',
2545
2499
        .arg = "FILE",
2546
2500
        .doc = "OpenPGP public key file base name",
2547
 
        .group = 1 },
2548
 
      { .name = "tls-privkey", .key = 't',
2549
 
        .arg = "FILE",
2550
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2551
 
        .doc = "TLS private key file base name",
2552
 
#else
2553
 
        .doc = "Dummy; ignored (requires GnuTLS 3.6.6)",
2554
 
#endif
2555
 
        .group = 1 },
2556
 
      { .name = "tls-pubkey", .key = 'T',
2557
 
        .arg = "FILE",
2558
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2559
 
        .doc = "TLS public key file base name",
2560
 
#else
2561
 
        .doc = "Dummy; ignored (requires GnuTLS 3.6.6)",
2562
 
#endif
2563
 
        .group = 1 },
 
2501
        .group = 2 },
2564
2502
      { .name = "dh-bits", .key = 129,
2565
2503
        .arg = "BITS",
2566
2504
        .doc = "Bit length of the prime number used in the"
2622
2560
      case 'p':                 /* --pubkey */
2623
2561
        pubkey = arg;
2624
2562
        break;
2625
 
      case 't':                 /* --tls-privkey */
2626
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2627
 
        tls_privkey = arg;
2628
 
#endif
2629
 
        break;
2630
 
      case 'T':                 /* --tls-pubkey */
2631
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2632
 
        tls_pubkey = arg;
2633
 
#endif
2634
 
        break;
2635
2563
      case 129:                 /* --dh-bits */
2636
2564
        errno = 0;
2637
2565
        tmpmax = strtoimax(arg, &tmp, 10);
2672
2600
        argp_state_help(state, state->out_stream,
2673
2601
                        (ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
2674
2602
                        & ~(unsigned int)ARGP_HELP_EXIT_OK);
2675
 
        __builtin_unreachable();
2676
2603
      case -3:                  /* --usage */
2677
2604
        argp_state_help(state, state->out_stream,
2678
2605
                        ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
2679
 
        __builtin_unreachable();
2680
2606
      case 'V':                 /* --version */
2681
2607
        fprintf_plus(state->out_stream, "%s\n", argp_program_version);
2682
2608
        exit(argp_err_exit_status);
2993
2919
    goto end;
2994
2920
  }
2995
2921
  
2996
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2997
 
  ret = init_gnutls_global(tls_pubkey, tls_privkey, dh_params_file, &mc);
2998
 
#elif GNUTLS_VERSION_NUMBER < 0x030600
2999
2922
  ret = init_gnutls_global(pubkey, seckey, dh_params_file, &mc);
3000
 
#else
3001
 
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
3002
 
#endif
3003
2923
  if(ret == -1){
3004
2924
    fprintf_plus(stderr, "init_gnutls_global failed\n");
3005
2925
    exitcode = EX_UNAVAILABLE;