Beispiel #1
0
Test::Result
PK_Encryption_Decryption_Test::run_one_test(const std::string&, const VarMap& vars)
   {
   const std::vector<uint8_t> plaintext  = get_req_bin(vars, "Msg");
   const std::vector<uint8_t> ciphertext = get_req_bin(vars, "Ciphertext");

   const std::string padding = get_opt_str(vars, "Padding", default_padding(vars));

   std::unique_ptr<Botan::RandomNumberGenerator> kat_rng;
   if(vars.count("Nonce"))
      {
      kat_rng.reset(new Fixed_Output_RNG(get_req_bin(vars, "Nonce")));
      }

   Test::Result result(algo_name() + "/" + padding + " decryption");

   std::unique_ptr<Botan::Private_Key> privkey = load_private_key(vars);

   // instead slice the private key to work around elgamal test inputs
   //std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey)));

   Botan::PK_Encryptor_EME encryptor(*privkey, padding);
   result.test_eq("encryption", encryptor.encrypt(plaintext, kat_rng ? *kat_rng : Test::rng()), ciphertext);

   Botan::PK_Decryptor_EME decryptor(*privkey, padding);
   result.test_eq("decryption", decryptor.decrypt(ciphertext), plaintext);

   check_invalid_ciphertexts(result, decryptor, plaintext, ciphertext);

   return result;
   }
Beispiel #2
0
Test::Result
PK_Signature_Generation_Test::run_one_test(const std::string&, const VarMap& vars)
   {
   const std::vector<uint8_t> message   = get_req_bin(vars, "Msg");
   const std::vector<uint8_t> signature = get_req_bin(vars, "Signature");
   const std::string padding = get_opt_str(vars, "Padding", default_padding(vars));

   std::unique_ptr<Botan::RandomNumberGenerator> rng;
   if(vars.count("Nonce"))
      {
      rng.reset(new Fixed_Output_RNG(get_req_bin(vars, "Nonce")));
      }

   Test::Result result(algo_name() + "/" + padding + " signature generation");

   std::unique_ptr<Botan::Private_Key> privkey = load_private_key(vars);
   std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey)));

   Botan::PK_Signer signer(*privkey, padding);
   Botan::PK_Verifier verifier(*pubkey, padding);

   const std::vector<uint8_t> generated_signature = signer.sign_message(message, rng ? *rng : Test::rng());
   result.test_eq("generated signature matches KAT", generated_signature, signature);

   result.test_eq("generated signature valid", verifier.verify_message(message, generated_signature), true);
   check_invalid_signatures(result, verifier, message, signature);
   result.test_eq("correct signature valid", verifier.verify_message(message, signature), true);

   return result;
   }
Beispiel #3
0
Test::Result PK_KEM_Test::run_one_test(const std::string&, const VarMap& vars)
   {
   const std::vector<uint8_t> K = get_req_bin(vars, "K");
   const std::vector<uint8_t> C0 = get_req_bin(vars, "C0");
   const std::vector<uint8_t> salt = get_opt_bin(vars, "Salt");
   const std::string kdf = get_req_str(vars, "KDF");

   Test::Result result(algo_name() + "/" + kdf + " KEM");

   std::unique_ptr<Botan::Private_Key> privkey = load_private_key(vars);

   const Botan::Public_Key& pubkey = *privkey;

   const size_t desired_key_len = K.size();

   std::unique_ptr<Botan::PK_KEM_Encryptor> enc;
   try
      {
      enc.reset(new Botan::PK_KEM_Encryptor(pubkey, Test::rng(), kdf));
      }
   catch(Botan::Lookup_Error&)
      {
      result.test_note("Skipping due to missing KDF: " + kdf);
      return result;
      }

   Fixed_Output_RNG fixed_output_rng(get_req_bin(vars, "R"));

   Botan::secure_vector<uint8_t> produced_encap_key, shared_key;
   enc->encrypt(produced_encap_key,
                shared_key,
                desired_key_len,
                fixed_output_rng,
                salt);

   result.test_eq("C0 matches", produced_encap_key, C0);
   result.test_eq("K matches", shared_key, K);

   std::unique_ptr<Botan::PK_KEM_Decryptor> dec;
   try
      {
      dec.reset(new Botan::PK_KEM_Decryptor(*privkey, Test::rng(), kdf));
      }
   catch(Botan::Lookup_Error& e)
      {
      result.test_note("Skipping test", e.what());
      return result;
      }

   const Botan::secure_vector<uint8_t> decr_shared_key =
      dec->decrypt(C0.data(), C0.size(),
                   desired_key_len,
                   salt.data(),
                   salt.size());

   result.test_eq("decrypted K matches", decr_shared_key, K);

   return result;
   }
int main(int argc, char** argv) {

  if(argc != 2) {
      fprintf(stderr, "ERROR: usage: <conf-file> \n");
      exit(1);
  }

  register_for_signals(close_db);
  
  parse_config_file(&config, argv[1]);

  priv_key = load_private_key(config.private_key_fname);

  db = bdb_open_env(config.db_env_fname, g_db_env_flags,
                    config.db_fname, g_db_flags | DB_CREATE);
  warm_db(db);

   // create global UNIX domain server sockets
   // to get replies from other threads
  child_finished_sock = openUnixServerSock(config.request_finished_sock,1000); 
  fd_set readset;
  struct timeval t,now;
  while(1) { 
      t.tv_sec = 1;
      t.tv_usec = 0; 

      FD_ZERO(&readset);
      FD_SET(child_finished_sock, &readset);
      int result = select(child_finished_sock + 1, &readset, NULL, NULL, &t); 

      if(result > 0) {
	gettimeofday(&now,NULL); 
        if(FD_ISSET(child_finished_sock, &readset)) {
          handle_finished_client(now.tv_sec);
        }
      }else if(result < 0) {
          fprintf(stderr, "ERROR: select: %s\n", strerror(errno));
      } 
  }

  close(child_finished_sock);
  bdb_close_env(db);
  return 0;
}
Beispiel #5
0
SSL_CTX *new_ctx(const neo4j_config_t *config, neo4j_logger_t *logger)
{
    SSL_CTX *ctx = SSL_CTX_new(TLSv1_method());
    if (ctx == NULL)
    {
        errno = openssl_error(logger, NEO4J_LOG_ERROR, __FILE__, __LINE__);
        return NULL;
    }

    if (SSL_CTX_set_cipher_list(ctx, "HIGH:!EXPORT:!aNULL@STRENGTH") != 1)
    {
        errno = openssl_error(logger, NEO4J_LOG_ERROR, __FILE__, __LINE__);
        goto failure;
    }

    // Necessary when using blocking sockets
    SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);

    // Caching should be done at the protocol layer anyway
    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);

    if (load_private_key(ctx, config, logger))
    {
        goto failure;
    }

    if (load_certificate_authorities(ctx, config, logger))
    {
        goto failure;
    }

    return ctx;

    int errsv;
failure:
    errsv = errno;
    SSL_CTX_free(ctx);
    errno = errsv;
    return NULL;
}
Beispiel #6
0
int main()
{
   EVP_PKEY      * priv_key   = 0;
   EVP_PKEY      * pub_key    = 0;
   char          * data       = "Hello World";
   int             data_len   = strlen(data);
   unsigned char * sig        = 0;
   int             sig_len    = 0;

   gen_keys( "priv.pem", "pub.pem" );

   priv_key   = load_private_key( "priv.pem" );
   pub_key    = load_public_key2( "pub.pem" );

   if (!priv_key || !pub_key)
   {
      printf("failed to load keys\n");
      return 1;
   }
   
   sig = sign_it( priv_key, EVP_sha1(), data, data_len, &sig_len );

   if (!sig)
   {
      printf("Failed to generate signature\n");
      return 1;
   }

   if ( verify_sig( pub_key, EVP_sha1(), data, data_len, sig, sig_len ) )
      printf("Signature matches!!\n");
   else
      printf("*** SIG FAILED ***\n");

   free(sig);
   EVP_PKEY_free (priv_key);
   EVP_PKEY_free (pub_key);

   return 0;
}
static int execute_openssl_auth_protocol(struct openssl_session_auth_context* ctx) {
    u32 client_certificate_length, server_certificate_length, private_key_length;
    char* client_certificate = NULL;
    char* server_certificate = NULL;
    char* private_key = NULL;
    int auth_result = 0;
    node_security_mode required_security_mode;
    int auth_mode = 2;
    uid_t user;
    struct in_addr remote_addr;
    int ret;

    ctx->status = AS_INPROGRESS;

    if ( ctx->fid->user == NULL ) {
        ctx->status = AS_REJECTED;
        pthread_cond_broadcast(&ctx->cond);
        return 0;
    }

    user = ctx->fid->user->uid;
    convert_addr(ctx->fid->conn->address, &remote_addr);

    required_security_mode = get_security_mode(user, remote_addr);

    if ( required_security_mode == REJECT ) {
        ctx->status = AS_REJECTED;
        pthread_cond_broadcast(&ctx->cond);
        return 0;
    }

    if ( required_security_mode == OPEN || required_security_mode == ENCRYPTED ) /* TODO: only encryption with no auth is not supported yet */
        auth_mode= 0;
    else if ( required_security_mode == AUTHENTICATED )
        auth_mode = 1;
    else if ( required_security_mode == SECURED )
        auth_mode = 2;

    if ( write_u32(ctx, auth_mode) != 4 ) {
        printf("Failed to send required mode to the client\n");
        ctx->status = AS_REJECTED;
        pthread_cond_broadcast(&ctx->cond);
        return 0;
    }

    if ( !auth_mode ) { /* Authentication is not required => we are done */
        ctx->status = AS_ACCEPTED;
        pthread_cond_broadcast(&ctx->cond);
        printf("Auth is not required for uid %d from host %s\n", user, ctx->fid->conn->address);
        return 1;
    }

    ret = exchange_certificates(ctx, &client_certificate, &client_certificate_length, &server_certificate, &server_certificate_length, &remote_addr);
    if ( ret )
        goto failed;

    if ( load_private_key(module_context->path_to_privatekey, module_context->privatekey_password, &private_key, &private_key_length) ) {
        printf("Failed to load private key\n");
        goto failed;
    }

    ret = verify_private_key_ownership(ctx, private_key, private_key_length, client_certificate, client_certificate_length);
    if ( ret )
        goto failed;

    if ( auth_mode == 2 )  { // If encryption is required
        ret = establish_symmetric_cipher(ctx, client_certificate, client_certificate_length);
        if ( ret )
            goto failed;
    }

    ctx->status = AS_ACCEPTED;
failed:
    free(private_key);
    free(server_certificate);
    free(client_certificate);
    if ( ctx->status == AS_INPROGRESS )
        ctx->status = AS_REJECTED;

    pthread_cond_broadcast(&ctx->cond);

    return auth_result;
}
Beispiel #8
0
int main(int ac, char **av)
{
    extern char *optarg;
    extern int optind;
    int opt, sock_in, sock_out, newsock, i, pid = 0, on = 1;
    socklen_t aux;
    int remote_major, remote_minor;
    int perm_denied = 0;
    int ret;
    fd_set fdset;
#ifdef HAVE_IPV6_SMTH
    struct sockaddr_in6 sin;
#else
    struct sockaddr_in sin;
#endif
    char buf[100];              /* Must not be larger than remote_version. */
    char remote_version[100];   /* Must be at least as big as buf. */
    char addr[STRLEN];
    char *comment;
    char *ssh_remote_version_string = NULL;
    FILE *f;

#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
    struct linger linger;
#endif                          /* SO_LINGER */
    int done;

    chdir(BBSHOME);
    /* Save argv[0]. */
    saved_argv = av;
    if (strchr(av[0], '/'))
        av0 = strrchr(av[0], '/') + 1;
    else
        av0 = av[0];

    /* Prevent core dumps to avoid revealing sensitive information. */
    signals_prevent_core();

    /* Set SIGPIPE to be ignored. */
    signal(SIGPIPE, SIG_IGN);

    /* Initialize configuration options to their default values. */
    initialize_server_options(&options);
    addr[0]=0;

    /* Parse command-line arguments. */
    while ((opt = getopt(ac, av, "f:a:p:b:k:h:g:diqV:")) != EOF) {
        switch (opt) {
        case 'f':
            config_file_name = optarg;
            break;
        case 'd':
            debug_flag = 1;
            break;
        case 'i':
            inetd_flag = 1;
            break;
        case 'q':
            options.quiet_mode = 1;
            break;
        case 'b':
            options.server_key_bits = atoi(optarg);
            break;
        case 'a':
            if(optarg[0])
                snprintf(addr,STRLEN,"%s",optarg);
            break;
        case 'p':
            if(isdigit(optarg[0]))
                options.port=atoi(optarg);
            break;
        case 'g':
            options.login_grace_time = atoi(optarg);
            break;
        case 'k':
            options.key_regeneration_time = atoi(optarg);
            break;
        case 'h':
            options.host_key_file = optarg;
            break;
        case 'V':
            ssh_remote_version_string = optarg;
            break;
        case '?':
        default:
#ifdef F_SECURE_COMMERCIAL

#endif                          /* F_SECURE_COMMERCIAL */
            fprintf(stderr, "sshd version %s [%s]\n", SSH_VERSION, HOSTTYPE);
            fprintf(stderr, "Usage: %s [options]\n", av0);
            fprintf(stderr, "Options:\n");
            fprintf(stderr, "  -f file    Configuration file (default %s/sshd_config)\n", ETCDIR);
            fprintf(stderr, "  -d         Debugging mode\n");
            fprintf(stderr, "  -i         Started from inetd\n");
            fprintf(stderr, "  -q         Quiet (no logging)\n");
            fprintf(stderr, "  -a addr    Bind to the specified address (default: all)\n");
            fprintf(stderr, "  -p port    Listen on the specified port (default: 22)\n");
            fprintf(stderr, "  -k seconds Regenerate server key every this many seconds (default: 3600)\n");
            fprintf(stderr, "  -g seconds Grace period for authentication (default: 300)\n");
            fprintf(stderr, "  -b bits    Size of server RSA key (default: 768 bits)\n");
            fprintf(stderr, "  -h file    File from which to read host key (default: %s)\n", HOST_KEY_FILE);
            fprintf(stderr, "  -V str     Remote version string already read from the socket\n");
            exit(1);
        }
    }

    /* Read server configuration options from the configuration file. */
    read_server_config(&options, config_file_name);

    /* Fill in default values for those options not explicitly set. */
    fill_default_server_options(&options);

    /* Check certain values for sanity. */
    if (options.server_key_bits < 512 || options.server_key_bits > 32768) {
        fprintf(stderr, "fatal: Bad server key size.\n");
        exit(1);
    }
    if (options.port < 1 || options.port > 65535) {
        fprintf(stderr, "fatal: Bad port number.\n");
        exit(1);
    }
    if (options.umask != -1) {
        umask(options.umask);
    }

    /* Check that there are no remaining arguments. */
    if (optind < ac) {
        fprintf(stderr, "fatal: Extra argument %.100s.\n", av[optind]);
        exit(1);
    }

    /* Initialize the log (it is reinitialized below in case we forked). */
    log_init(av0, debug_flag && !inetd_flag, debug_flag || options.fascist_logging, options.quiet_mode, options.log_facility);

    debug("sshd version %.100s [%.100s]", SSH_VERSION, HOSTTYPE);

    /* Load the host key.  It must have empty passphrase. */
    done = load_private_key(geteuid(), options.host_key_file, "", &sensitive_data.host_key, &comment);

    if (!done) {
        if (debug_flag) {
            fprintf(stderr, "Could not load host key: %.200s\n", options.host_key_file);
            fprintf(stderr, "fatal: Please check that you have sufficient permissions and the file exists.\n");
        } else {
            log_init(av0, !inetd_flag, 1, 0, options.log_facility);
            error("fatal: Could not load host key: %.200s.  Check path and permissions.", options.host_key_file);
        }
        exit(1);
    }
    xfree(comment);

    /* If not in debugging mode, and not started from inetd, disconnect from
       the controlling terminal, and fork.  The original process exits. */
    if (!debug_flag && !inetd_flag)
#ifdef HAVE_DAEMON
        if (daemon(0, 0) < 0)
            error("daemon: %.100s", strerror(errno));
    chdir(BBSHOME);
#else                           /* HAVE_DAEMON */
    {
#ifdef TIOCNOTTY
        int fd;
#endif                          /* TIOCNOTTY */

        /* Fork, and have the parent exit.  The child becomes the server. */
        if (fork())
            exit(0);

        /* Redirect stdin, stdout, and stderr to /dev/null. */
        freopen("/dev/null", "r", stdin);
        freopen("/dev/null", "w", stdout);
        freopen("/dev/null", "w", stderr);

        /* Disconnect from the controlling tty. */
#ifdef TIOCNOTTY
        fd = open("/dev/tty", O_RDWR | O_NOCTTY);
        if (fd >= 0) {
            (void) ioctl(fd, TIOCNOTTY, NULL);
            close(fd);
        }
#endif                          /* TIOCNOTTY */
#ifdef HAVE_SETSID
#ifdef ultrix
        setpgrp(0, 0);
#else                           /* ultrix */
        if (setsid() < 0)
            error("setsid: %.100s", strerror(errno));
#endif
#endif                          /* HAVE_SETSID */
    }
#endif                          /* HAVE_DAEMON */

    /* Reinitialize the log (because of the fork above). */
    log_init(av0, debug_flag && !inetd_flag, debug_flag || options.fascist_logging, options.quiet_mode, options.log_facility);

    /* Check that server and host key lengths differ sufficiently.  This is
       necessary to make double encryption work with rsaref.  Oh, I hate
       software patents. */
    if (options.server_key_bits > sensitive_data.host_key.bits - SSH_KEY_BITS_RESERVED && options.server_key_bits < sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED) {
        options.server_key_bits = sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED;
        debug("Forcing server key to %d bits to make it differ from host key.", options.server_key_bits);
    }

    /* Initialize memory allocation so that any freed MP_INT data will be
       zeroed. */
    rsa_set_mp_memory_allocation();

    /* Do not display messages to stdout in RSA code. */
    rsa_set_verbose(debug_flag);

    /* Initialize the random number generator. */
    debug("Initializing random number generator; seed file %.200s", options.random_seed_file);
    random_initialize(&sensitive_data.random_state, geteuid(), options.random_seed_file);

    /* Chdir to the root directory so that the current disk can be unmounted
       if desired. */

    idle_timeout = options.idle_timeout;

    /* Start listening for a socket, unless started from inetd. */
    if (inetd_flag) {
        int s1, s2;

        s1 = dup(0);            /* Make sure descriptors 0, 1, and 2 are in use. */
        s2 = dup(s1);
        sock_in = dup(0);
        sock_out = dup(1);
        /* We intentionally do not close the descriptors 0, 1, and 2 as our
           code for setting the descriptors won\'t work if ttyfd happens to
           be one of those. */
        debug("inetd sockets after dupping: %d, %d", sock_in, sock_out);

        /* Generate an rsa key. */
        log_msg("Generating %d bit RSA key.", options.server_key_bits);
        rsa_generate_key(&sensitive_data.private_key, &public_key, &sensitive_data.random_state, options.server_key_bits);
        random_save(&sensitive_data.random_state, geteuid(), options.random_seed_file);
        log_msg("RSA key generation complete.");
    } else {
        /* Create socket for listening. */
#ifdef HAVE_IPV6_SMTH
        listen_sock = socket(AF_INET6, SOCK_STREAM, 0);
#else       
        listen_sock = socket(AF_INET, SOCK_STREAM, 0);
#endif
        if (listen_sock < 0)
            fatal("socket: %.100s", strerror(errno));

        /* Set socket options.  We try to make the port reusable and have it
           close as fast as possible without waiting in unnecessary wait states
           on close. */
        setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on));
#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
        linger.l_onoff = 1;
        linger.l_linger = 15;
        setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
#endif                          /* SO_LINGER */

        /* Initialize the socket address. */
        memset(&sin, 0, sizeof(sin));
#ifdef HAVE_IPV6_SMTH
        sin.sin6_family = AF_INET6;
        if ( inet_pton(AF_INET6, addr, &(sin.sin6_addr)) <= 0 )
            sin.sin6_addr = in6addr_any;
        sin.sin6_port = htons(options.port);
#else
        sin.sin_family = AF_INET;
        if ( inet_pton(AF_INET, addr, &(sin.sin_addr)) <= 0 )
            sin.sin_addr.s_addr = htonl(INADDR_ANY);
        sin.sin_port = htons(options.port);
#endif
        /* Bind the socket to the desired port. */
        if (bind(listen_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
            error("bind: %.100s", strerror(errno));
            shutdown(listen_sock, 2);
            close(listen_sock);
            fatal("Bind to port %d failed: %.200s.", options.port, strerror(errno));
        }
        /* COMMAN : setuid to bbs */

        if(setgid(BBSGID)==-1)
            exit(8);
        if(setuid(BBSUID)==-1)
            exit(8);

#if 0 /* etnlegend, 2006.10.31 ... */
        if (!debug_flag) {
            /* Record our pid in /etc/sshd_pid to make it easier to kill the
               correct sshd.  We don\'t want to do this before the bind above
               because the bind will fail if there already is a daemon, and this
               will overwrite any old pid in the file. */
            f = fopen(options.pid_file, "w");
            if (f) {
                fprintf(f, "%u\n", (unsigned int) getpid());
                fclose(f);
            }
        }
#endif

        /* Start listening on the port. */
        log_msg("Server listening on port %d.", options.port);
        if (listen(listen_sock, 5) < 0)
            fatal("listen: %.100s", strerror(errno));

        /* Generate an rsa key. */
        log_msg("Generating %d bit RSA key.", options.server_key_bits);
        rsa_generate_key(&sensitive_data.private_key, &public_key, &sensitive_data.random_state, options.server_key_bits);
        random_save(&sensitive_data.random_state, geteuid(), options.random_seed_file);
        log_msg("RSA key generation complete.");

        /* Schedule server key regeneration alarm. */
        signal(SIGALRM, key_regeneration_alarm);
        alarm(options.key_regeneration_time);

        /* Arrange to restart on SIGHUP.  The handler needs listen_sock. */
        signal(SIGHUP, sighup_handler);
        signal(SIGTERM, sigterm_handler);
        signal(SIGQUIT, sigterm_handler);

        /* AIX sends SIGDANGER when memory runs low.  The default action is
           to terminate the process.  This sometimes makes it difficult to
           log in and fix the problem. */

#ifdef SIGDANGER
        signal(SIGDANGER, sigdanger_handler);
#endif                          /* SIGDANGER */

        /* Arrange SIGCHLD to be caught. */
        signal(SIGCHLD, main_sigchld_handler);


        if(!debug_flag){
            if(!addr[0])
                sprintf(buf,"var/sshbbsd.%d.pid",options.port);
            else
                sprintf(buf,"var/sshbbsd.%d_%s.pid",options.port,addr);
            if((f=fopen(buf,"w"))){
                fprintf(f,"%d\n",(int)getpid());
                fclose(f);
            }
        }

        /* Stay listening for connections until the system crashes or the
           daemon is killed with a signal. */
        for (;;) {
            if (received_sighup)
                sighup_restart();

            /* Wait in select until there is a connection. */
            FD_ZERO(&fdset);
            FD_SET(listen_sock, &fdset);
            ret = select(listen_sock + 1, &fdset, NULL, NULL, NULL);
            if (ret < 0 || !FD_ISSET(listen_sock, &fdset)) {
                if (errno == EINTR)
                    continue;
                error("select: %.100s", strerror(errno));
                continue;
            }

            aux = sizeof(sin);
            newsock = accept(listen_sock, (struct sockaddr *) &sin, &aux);
            if (newsock < 0) {
                if (errno == EINTR)
                    continue;
                error("accept: %.100s", strerror(errno));
                continue;
            }

            /* Got connection.  Fork a child to handle it, unless we are in
               debugging mode. */
            if (debug_flag) {
                /* In debugging mode.  Close the listening socket, and start
                   processing the connection without forking. */
                debug("Server will not fork when running in debugging mode.");
                close(listen_sock);
                sock_in = newsock;
                sock_out = newsock;
                pid = getpid();
#ifdef LIBWRAP
                {
                    struct request_info req;

                    signal(SIGCHLD, SIG_DFL);

                    request_init(&req, RQ_DAEMON, av0, RQ_FILE, newsock, NULL);
                    fromhost(&req);
                    if (!hosts_access(&req))
                        refuse(&req);
                    syslog(allow_severity, "connect from %s", eval_client(&req));
                }
#endif                          /* LIBWRAP */
                break;
            } else {
#ifdef CHECK_IP_LINK
#ifdef HAVE_IPV6_SMTH
                if (check_IP_lists(sin.sin6_addr)==0)
#else
                if (check_IP_lists(sin.sin_addr.s_addr)==0) 
#endif
#endif
                /* Normal production daemon.  Fork, and have the child process
                   the connection.  The parent continues listening. */
                if ((pid = fork()) == 0) {
                    /* Child.  Close the listening socket, and start using
                       the accepted socket.  Reinitialize logging (since our
                       pid has changed).  We break out of the loop to handle
                       the connection. */
                    close(listen_sock);
                    sock_in = newsock;
                    sock_out = newsock;
#ifdef LIBWRAP
                    {
                        struct request_info req;

                        signal(SIGCHLD, SIG_DFL);

                        request_init(&req, RQ_DAEMON, av0, RQ_FILE, newsock, NULL);
                        fromhost(&req);
                        if (!hosts_access(&req))
                            refuse(&req);
                        syslog(allow_severity, "connect from %s", eval_client(&req));
                    }
#endif                          /* LIBWRAP */

                    log_init(av0, debug_flag && !inetd_flag, options.fascist_logging || debug_flag, options.quiet_mode, options.log_facility);
                    break;
                }
            }

            /* Parent.  Stay in the loop. */
            if (pid < 0)
                error("fork: %.100s", strerror(errno));
            else
                debug("Forked child %d.", pid);

            /* Mark that the key has been used (it was "given" to the child). */
            key_used = 1;

            random_acquire_light_environmental_noise(&sensitive_data.random_state);

            /* Close the new socket (the child is now taking care of it). */
            close(newsock);
        }
    }

    /* This is the child processing a new connection. */

    /* Disable the key regeneration alarm.  We will not regenerate the key
       since we are no longer in a position to give it to anyone.  We will
       not restart on SIGHUP since it no longer makes sense. */
    alarm(0);
    signal(SIGALRM, SIG_DFL);
    signal(SIGHUP, SIG_DFL);
    signal(SIGTERM, SIG_DFL);
    signal(SIGQUIT, SIG_DFL);
    signal(SIGCHLD, SIG_DFL);

    /* Set socket options for the connection.  We want the socket to close
       as fast as possible without waiting for anything.  If the connection
       is not a socket, these will do nothing. */
    /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
    linger.l_onoff = 1;
    linger.l_linger = 15;
    setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
#endif                          /* SO_LINGER */

    /* Register our connection.  This turns encryption off because we do not
       have a key. */
    packet_set_connection(sock_in, sock_out, &sensitive_data.random_state);

    /* Log the connection. */
    log_msg("Connection from %.100s port %d", get_remote_ipaddr(), get_remote_port());

    /* Check whether logins are denied from this host. */
    {
        const char *hostname = get_canonical_hostname();
        const char *ipaddr = get_remote_ipaddr();
        int i;

        if (options.num_deny_hosts > 0) {
            for (i = 0; i < options.num_deny_hosts; i++)
                if (match_host(hostname, ipaddr, options.deny_hosts[i]))
                    perm_denied = 1;
        }
        if ((!perm_denied) && options.num_allow_hosts > 0) {
            for (i = 0; i < options.num_allow_hosts; i++)
                if (match_host(hostname, ipaddr, options.allow_hosts[i]))
                    break;
            if (i >= options.num_allow_hosts)
                perm_denied = 1;
        }
        if (perm_denied && options.silent_deny) {
            close(sock_in);
            close(sock_out);
            exit(0);
        }
    }

    /* We don't want to listen forever unless the other side successfully
       authenticates itself.  So we set up an alarm which is cleared after
       successful authentication.  A limit of zero indicates no limit.
       Note that we don't set the alarm in debugging mode; it is just annoying
       to have the server exit just when you are about to discover the bug. */
    signal(SIGALRM, grace_alarm_handler);
    if (!debug_flag)
        alarm(options.login_grace_time);


    if (ssh_remote_version_string == NULL) {
        /* Send our protocol version identification. */
        snprintf(buf, sizeof(buf), "SSH-%d.%d-%.50s", PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
        strcat(buf, "\n");
        if (write(sock_out, buf, strlen(buf)) != strlen(buf))
            fatal_severity(SYSLOG_SEVERITY_INFO, "Could not write ident string.");
    }

    if (ssh_remote_version_string == NULL) {
        /* Read other side\'s version identification. */
        for (i = 0; i < sizeof(buf) - 1; i++) {
            if (read(sock_in, &buf[i], 1) != 1)
                fatal_severity(SYSLOG_SEVERITY_INFO, "Did not receive ident string.");
            if (buf[i] == '\r') {
                buf[i] = '\n';
                buf[i + 1] = 0;
                break;
            }
            if (buf[i] == '\n') {
                /* buf[i] == '\n' */
                buf[i + 1] = 0;
                break;
            }
        }
        buf[sizeof(buf) - 1] = 0;
    } else {
        strncpy(buf, ssh_remote_version_string, sizeof(buf) - 1);
        buf[sizeof(buf) - 1] = 0;
    }

    /* Check that the versions match.  In future this might accept several
       versions and set appropriate flags to handle them. */
    if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) != 3) {
        const char *s = "Protocol mismatch.\n";

        (void) write(sock_out, s, strlen(s));
        close(sock_in);
        close(sock_out);
        fatal_severity(SYSLOG_SEVERITY_INFO, "Bad protocol version identification: %.100s", buf);
    }
    debug("Client protocol version %d.%d; client software version %.100s", remote_major, remote_minor, remote_version);

    switch (check_emulation(remote_major, remote_minor, NULL, NULL)) {
    case EMULATE_MAJOR_VERSION_MISMATCH:
        {
            const char *s = "Protocol major versions differ.\n";

            (void) write(sock_out, s, strlen(s));
            close(sock_in);
            close(sock_out);
            fatal_severity(SYSLOG_SEVERITY_INFO, "Protocol major versions differ: %d vs. %d", PROTOCOL_MAJOR, remote_major);
        }
        break;
    case EMULATE_VERSION_TOO_OLD:
        packet_disconnect("Your ssh version is too old and is no " "longer supported.  Please install a newer version.");
        break;
    case EMULATE_VERSION_NEWER:
        packet_disconnect("This server does not support your " "new ssh version.");
        break;
    case EMULATE_VERSION_OK:
        break;
    default:
        fatal("Unexpected return value from check_emulation.");
    }

    if (perm_denied) {
        const char *hostname = get_canonical_hostname();

        log_msg("Connection from %.200s not allowed.\n", hostname);
        packet_disconnect("Sorry, you are not allowed to connect.");
     /*NOTREACHED*/}

    packet_set_nonblocking();

    /* Handle the connection.   We pass as argument whether the connection
       came from a privileged port. */
    do_connection(get_remote_port() < 1024);

    /* The connection has been terminated. */
    log_msg("Closing connection to %.100s", get_remote_ipaddr());
    packet_close();
    exit(0);
}
Beispiel #9
0
Test::Result
PK_Signature_Generation_Test::run_one_test(const std::string&, const VarMap& vars)
   {
   const std::vector<uint8_t> message   = get_req_bin(vars, "Msg");
   const std::vector<uint8_t> signature = get_req_bin(vars, "Signature");
   const std::string padding = get_opt_str(vars, "Padding", default_padding(vars));

   Test::Result result(algo_name() + "/" + padding + " signature generation");

   std::unique_ptr<Botan::Private_Key> privkey = load_private_key(vars);
   std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey)));

   for(auto&& sign_provider : possible_pk_providers())
      {
      std::unique_ptr<Botan::PK_Signer> signer;

      try
         {
         signer.reset(new Botan::PK_Signer(*privkey, padding, Botan::IEEE_1363, sign_provider));
         }
      catch(Botan::Lookup_Error&)
         {
         //result.test_note("Skipping signing with " + sign_provider);
         continue;
         }

      std::unique_ptr<Botan::RandomNumberGenerator> rng;
      if(vars.count("Nonce"))
         {
         rng.reset(new Fixed_Output_RNG(get_req_bin(vars, "Nonce")));
         }

      const std::vector<uint8_t> generated_signature =
         signer->sign_message(message, rng ? *rng : Test::rng());

      if(sign_provider == "base")
         {
         result.test_eq("generated signature matches KAT", generated_signature, signature);
         }

      for(auto&& verify_provider : possible_pk_providers())
         {
         std::unique_ptr<Botan::PK_Verifier> verifier;

         try
            {
            verifier.reset(new Botan::PK_Verifier(*pubkey, padding, Botan::IEEE_1363, verify_provider));
            }
         catch(Botan::Lookup_Error&)
            {
            //result.test_note("Skipping verifying with " + verify_provider);
            continue;
            }

         if(!result.test_eq("generated signature valid",
                            verifier->verify_message(message, generated_signature), true))
            {
            result.test_failure("generated signature", generated_signature);
            }

         check_invalid_signatures(result, *verifier, message, signature);
         result.test_eq("KAT signature valid", verifier->verify_message(message, signature), true);
         }
      }

   return result;
   }
Beispiel #10
0
/*
 * initialize tls virtual domains
 */
int
init_tls_domains(struct tls_domain *d)
{
	struct tls_domain *dom;

	dom = d;
	while (d) {
		if (d->name.len) {
			LM_INFO("Processing TLS domain '%.*s'\n",
				d->name.len, ZSW(d->name.s));
		} else {
			LM_INFO("Processing TLS domain [%s:%d]\n",
				ip_addr2a(&d->addr), d->port);
		}

		/*
		* set method
		*/
		if (d->method == TLS_METHOD_UNSPEC) {
			LM_DBG("no method for tls[%s:%d], using default\n",
				ip_addr2a(&d->addr), d->port);
			d->method = tls_method;
		}

		/*
		* create context
		*/
		d->ctx = SSL_CTX_new(ssl_methods[d->method - 1]);
		if (d->ctx == NULL) {
			LM_ERR("cannot create ssl context for "
				"tls[%s:%d]\n", ip_addr2a(&d->addr), d->port);
			return -1;
		}
		if (init_ssl_ctx_behavior( d ) < 0)
			return -1;

		/*
		* load certificate
		*/
		if (!d->cert_file) {
			LM_NOTICE("no certificate for tls[%s:%d] defined, using default"
					"'%s'\n", ip_addr2a(&d->addr), d->port,	tls_cert_file);
			d->cert_file = tls_cert_file;
		}
		if (load_certificate(d->ctx, d->cert_file) < 0)
			return -1;

		/*
		* load ca
		*/
		if (!d->ca_file) {
			LM_NOTICE("no CA for tls[%s:%d] defined, "
				"using default '%s'\n", ip_addr2a(&d->addr), d->port,
				tls_ca_file);
			d->ca_file = tls_ca_file;
		}
		if (d->ca_file && load_ca(d->ctx, d->ca_file) < 0)
			return -1;

		/*
		* load ca from directory
		*/
		if (!d->ca_directory) {

			LM_NOTICE("no CA for tls[%s:%d] defined, "
				"using default '%s'\n", ip_addr2a(&d->addr), d->port,
				 tls_ca_dir);
			d->ca_directory = tls_ca_dir;
		}

		if (d->ca_directory && load_ca_dir(d->ctx, d->ca_directory) < 0)
			return -1;

		d = d->next;
	}

	/*
	* load all private keys as the last step (may prompt for password)
	*/
	d = dom;
	while (d) {
		if (!d->pkey_file) {
			LM_NOTICE("no private key for tls[%s:%d] defined, using default"
					"'%s'\n", ip_addr2a(&d->addr), d->port, tls_pkey_file);
			d->pkey_file = tls_pkey_file;
		}
		if (load_private_key(d->ctx, d->pkey_file) < 0)
			return -1;
		d = d->next;
	}
	return 0;
}
Beispiel #11
0
/*
 * called once from main.c (main process) 
 */
int
init_tls(void)
{
	struct tls_domain *d;
	DBG("init_tls: Entered\n");
#if OPENSSL_VERSION_NUMBER < 0x00907000L
	LOG(L_ERR, "WARNING! You are using an old version of OpenSSL (< 0.9.7). Upgrade!\n");
#endif
	LOG(L_ALERT, "WARNING! TLS is considered as an EXPERIMENTAL module\n" );	
	/*
		* this has to be called before any function calling CRYPTO_malloc,
		* CRYPTO_malloc will set allow_customize in openssl to 0 
		*/
	if (!CRYPTO_set_mem_functions(ser_malloc, ser_realloc, ser_free)) {
		LOG(L_ERR,
			"init_tls: Unable to set the memory allocation functions\n");
		return -1;
	}
	
	SSL_library_init();
	SSL_load_error_strings();
	init_ssl_methods();

	/*
	 * initialize default context first 
	 */
	default_ctx = SSL_CTX_new(ssl_methods[tls_method - 1]);
	if (default_ctx == NULL) {
		LOG(L_ERR, "init_tls: Cannot create default ssl context\n");
		return -1;
	}
	init_ssl_ctx_behavior( default_ctx );
	if (load_certificate(default_ctx, tls_cert_file) < 0)
		return -1;
	if (tls_ca_file && load_ca(default_ctx, tls_ca_file) < 0)
		return -1;
	if (load_private_key(default_ctx, tls_pkey_file) < 0)
		return -1;

	/*
	 * now initialize tls virtual domains 
	 */
	d = tls_domains;
	while (d) {
		DBG("init_tls: Processing TLS domain [%s:%d]\n",
				ip_addr2a(&d->addr), d->port);
		/*
		* create context 
		*/
		if (d->method == TLS_METHOD_UNSPEC) {
			DBG("init_tls: No method for tls[%s:%d], using default\n",
			ip_addr2a(&d->addr), d->port);
			d->method = tls_method;
		}
	
		d->ctx = SSL_CTX_new(ssl_methods[d->method - 1]);
		if (d->ctx == NULL) {
			LOG(L_ERR,
				"init_tls: Cannot create ssl context for tls[%s:%d]\n",
				ip_addr2a(&d->addr), d->port);
			return -1;
		}
		init_ssl_ctx_behavior( d->ctx );
		/*
		* load certificate 
		*/
		if (!d->cert_file) {
			LOG(L_NOTICE,
				"init_tls: No certificate for tls[%s:%d] defined, using default '%s'\n",
				ip_addr2a(&d->addr), d->port, tls_cert_file);
			d->cert_file = tls_cert_file;
		}
		if (load_certificate(d->ctx, d->cert_file) < 0)
			return -1;
	
		/*
		* load ca 
		*/
		if (!d->ca_file) {
			LOG(L_NOTICE,
				"init_tls: No CA for tls[%s:%d] defined, using default '%s'\n",
				ip_addr2a(&d->addr), d->port, tls_ca_file);
			d->ca_file = tls_ca_file;
		}
		if (d->ca_file && load_ca(d->ctx, d->ca_file) < 0)
			return -1;
		d = d->next;
	}

	/*
		* load all private keys as the last step (may prompt for password) 
		*/
	d = tls_domains;
	while (d) {
		if (!d->pkey_file) {
			LOG(L_NOTICE,
				"init_tls: No private key for tls[%s:%d] defined, using default '%s'\n",
				ip_addr2a(&d->addr), d->port, tls_pkey_file);
			d->pkey_file = tls_pkey_file;
		}
		if (load_private_key(d->ctx, d->pkey_file) < 0)
			return -1;
		d = d->next;
	}
	/*
	 * we are all set 
	 */
	return 0;
}
Beispiel #12
0
Test::Result
PK_Encryption_Decryption_Test::run_one_test(const std::string&, const VarMap& vars)
   {
   const std::vector<uint8_t> plaintext  = get_req_bin(vars, "Msg");
   const std::vector<uint8_t> ciphertext = get_req_bin(vars, "Ciphertext");

   const std::string padding = get_opt_str(vars, "Padding", default_padding(vars));

   Test::Result result(algo_name() + "/" + padding + " decryption");

   std::unique_ptr<Botan::Private_Key> privkey = load_private_key(vars);

   // instead slice the private key to work around elgamal test inputs
   //std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey)));
   Botan::Public_Key* pubkey = privkey.get();

   for(auto&& enc_provider : possible_pk_providers())
      {
      std::unique_ptr<Botan::PK_Encryptor> encryptor;

      try
         {
         encryptor.reset(new Botan::PK_Encryptor_EME(*pubkey, padding, enc_provider));
         }
      catch(Botan::Lookup_Error&)
         {
         //result.test_note("Skipping encryption with provider " + enc_provider);
         continue;
         }

      std::unique_ptr<Botan::RandomNumberGenerator> kat_rng;
      if(vars.count("Nonce"))
         {
         kat_rng.reset(new Fixed_Output_RNG(get_req_bin(vars, "Nonce")));
         }

      const std::vector<uint8_t> generated_ciphertext =
         encryptor->encrypt(plaintext, kat_rng ? *kat_rng : Test::rng());

      if(enc_provider == "base")
         {
         result.test_eq("generated ciphertext matches KAT", generated_ciphertext, ciphertext);
         }

      for(auto&& dec_provider : possible_pk_providers())
         {
         std::unique_ptr<Botan::PK_Decryptor> decryptor;

         try
            {
            decryptor.reset(new Botan::PK_Decryptor_EME(*privkey, padding, dec_provider));
            }
         catch(Botan::Lookup_Error&)
            {
            //result.test_note("Skipping decryption with provider " + dec_provider);
            continue;
            }

         result.test_eq("decryption of KAT", decryptor->decrypt(ciphertext), plaintext);
         check_invalid_ciphertexts(result, *decryptor, plaintext, ciphertext);
         result.test_eq("decryption of generated ciphertext",
                        decryptor->decrypt(generated_ciphertext), plaintext);
         }
      }

   return result;
   }
Beispiel #13
0
int main(int argc, char *argv[])
{
    CREATE_LOG("./");

    auto desc = create_descriptions();
    auto vm = parse_options(argc, argv, desc);
    if(vm.count("help"))
    {
        std::cout << desc << std::endl;
        return 1;
    }

    Botan::LibraryInitializer init;

    auto host = vm["host"].as<std::string>();
    auto port = vm["port"].as<std::string>();
    auto pass = vm.count("pass") ? vm["pass"].as<std::string>() : prompt_pass();

    auto key = vm["key"].as<std::string>();

    auto pkey = load_private_key(key, pass);
    CHECK(pkey);


    //it is important the tcp_connection manager is created before
    //the input tcp_connection is made. This is because tcp on
    //linux requires that binds to the same port are made before
    //a listen is made.
    n::connection_manager con{POOL_SIZE, port};
    sc::session_library sec{*pkey};
    user_info_map users;

    u::bytes data;
    while(true)
    try
    {
        n::endpoint ep;
        if(!con.receive(ep, data))
        {
            u::sleep_thread(THREAD_SLEEP);
            continue;
        }

        //decrypt message
        auto sid = n::make_address_str(ep);
        data = sec.decrypt(sid, data);

        //parse message
        m::message m;
        u::decode(data, m);

        if(m.meta.type == ms::GREET_REGISTER)
        {
            ms::greet_register r{m};
            register_user(con, sec, ep, r, users);
        }
        else if(m.meta.type == ms::GREET_FIND_REQUEST)
        {
            ms::greet_find_request r{m};
            find_user(con, sec,  ep, r, users);
        }
        else if(m.meta.type == ms::GREET_KEY_REQUEST)
        {
            ms::greet_key_request r{m};
            send_pub_key(con, sec, ep, r, users, *pkey);
        }
    }
    catch(std::exception& e)
    {
        LOG << "error parsing message: " << e.what() << std::endl;
        LOG << "message: " << u::to_str(data) << std::endl;
    }
    catch(...)
    {
        LOG << "unknown error parsing message: " << std::endl;
        LOG << "message: " << u::to_str(data) << std::endl;
    }
}
Beispiel #14
0
int main(int argc, char *argv[])
{
    CREATE_LOG("./");

    auto desc = create_descriptions();
    auto vm = parse_options(argc, argv, desc);
    if(vm.count("help"))
    {
        std::cout << desc << std::endl;
        return 1;
    }

    Botan::LibraryInitializer init;

    auto host = vm["host"].as<std::string>();
    auto port = vm["port"].as<int>();
    auto pass = vm.count("pass") ? vm["pass"].as<std::string>() : prompt_pass();
    auto key = vm["key"].as<std::string>();

    auto pkey = load_private_key(key, pass);
    CHECK(pkey);

    n::connection_manager con{POOL_SIZE, static_cast<n::port_type>(port)};
    sc::encrypted_channels sec{*pkey};
    user_info_map users;

    u::bytes data;
    while(true)
    try
    {
        n::endpoint ep;
        if(!con.receive(ep, data))
        {
            u::sleep_thread(THREAD_SLEEP);
            continue;
        }

        //decrypt message
        auto sid = n::make_address_str(ep);
        sc::encryption_type et;
        data = sec.decrypt(sid, data, et);
        data = u::uncompress(data);

        //parse message
        m::message m;
        u::decode(data, m);

        if(m.meta.type == ms::GREET_REGISTER)
        {
            if(et != sc::encryption_type::asymmetric) continue;

            ms::greet_register r{m};
            register_user(con, sec, ep, r, users);
        }
        else if(m.meta.type == ms::GREET_FIND_REQUEST)
        {
            if(et != sc::encryption_type::asymmetric) continue;

            ms::greet_find_request r{m};
            find_user(con, sec,  ep, r, users);
        }
        else if(m.meta.type == ms::GREET_KEY_REQUEST)
        {
            ms::greet_key_request r{m};
            send_pub_key(con, sec, ep, r, users, *pkey);
        }
    }
    catch(std::exception& e)
    {
        LOG << "error parsing message: " << e.what() << std::endl;
    }
    catch(...)
    {
        LOG << "unknown error parsing message: " << std::endl;
    }
}
Beispiel #15
0
int main(int argc, char **argv)
{
    const char *host, *port;
    struct sockaddr_storage sa;
    socklen_t salen;
    int ch;

    while ((ch = getopt(argc, argv, "c:k:l:r:s:Vvh")) != -1) {
        switch (ch) {
        case 'c':
            load_certificate_chain(&tlsctx, optarg);
            break;
        case 'k':
            load_private_key(&tlsctx, optarg);
            break;
        case 'l':
            setup_log_secret(&tlsctx, optarg);
            break;
        case 'r':
            if (sscanf(optarg, "%" PRIu32, &ctx.initial_rto) != 1) {
                fprintf(stderr, "invalid argument passed to `-r`\n");
                exit(1);
            }
            break;
        case 's':
            ctx.stateless_retry.enforce_use = 1;
            ctx.stateless_retry.key = optarg;
            if (strlen(ctx.stateless_retry.key) < tlsctx.cipher_suites[0]->hash->digest_size) {
                fprintf(stderr, "secret for stateless retry is too short (should be at least %zu bytes long)\n",
                        tlsctx.cipher_suites[0]->hash->digest_size);
                exit(1);
            }
            break;
        case 'V':
            setup_verify_certificate(&tlsctx);
            break;
        case 'v':
            ++verbosity;
            break;
        default:
            usage(argv[0]);
            exit(1);
        }
    }
    argc -= optind;
    argv += optind;

    if (verbosity != 0)
        ctx.debug_log = quicly_default_debug_log;

    if (tlsctx.certificates.count != 0 || tlsctx.sign_certificate != NULL) {
        /* server */
        if (tlsctx.certificates.count == 0 || tlsctx.sign_certificate == NULL) {
            fprintf(stderr, "-ck and -k options must be used together\n");
            exit(1);
        }
    } else {
        /* client */
    }
    if (argc != 2) {
        fprintf(stderr, "missing host and port\n");
        exit(1);
    }
    host = (--argc, *argv++);
    port = (--argc, *argv++);

    if (resolve_address((void *)&sa, &salen, host, port, SOCK_DGRAM, IPPROTO_UDP) != 0)
        exit(1);

    return tlsctx.certificates.count != 0 ? run_server((void *)&sa, salen) : run_client((void *)&sa, salen, host);
}
Beispiel #16
0
Test::Result
PK_Encryption_Decryption_Test::run_one_test(const std::string& pad_hdr, const VarMap& vars)
   {
   const std::vector<uint8_t> plaintext  = get_req_bin(vars, "Msg");
   const std::vector<uint8_t> ciphertext = get_req_bin(vars, "Ciphertext");
   const std::string padding = choose_padding(vars, pad_hdr);

   Test::Result result(algo_name() + (padding.empty() ? padding : "/" + padding) + " decryption");

   std::unique_ptr<Botan::Private_Key> privkey = load_private_key(vars);

   // instead slice the private key to work around elgamal test inputs
   //std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey)));
   Botan::Public_Key* pubkey = privkey.get();

   std::vector<std::unique_ptr<Botan::PK_Decryptor>> decryptors;

   for(auto const& dec_provider : possible_providers(algo_name()))
      {
      std::unique_ptr<Botan::PK_Decryptor> decryptor;

      try
         {
         decryptor.reset(new Botan::PK_Decryptor_EME(*privkey, Test::rng(), padding, dec_provider));
         }
      catch(Botan::Lookup_Error&)
         {
         continue;
         }

      Botan::secure_vector<uint8_t> decrypted;
      try
         {
         decrypted = decryptor->decrypt(ciphertext);
         }
      catch(Botan::Exception& e)
         {
         result.test_failure("Failed to decrypt KAT ciphertext", e.what());
         }

      result.test_eq(dec_provider, "decryption of KAT", decrypted, plaintext);
      check_invalid_ciphertexts(result, *decryptor, plaintext, ciphertext);
      }


   for(auto const& enc_provider : possible_providers(algo_name()))
      {
      std::unique_ptr<Botan::PK_Encryptor> encryptor;

      try
         {
         encryptor.reset(new Botan::PK_Encryptor_EME(*pubkey, Test::rng(), padding, enc_provider));
         }
      catch(Botan::Lookup_Error&)
         {
         continue;
         }

      std::unique_ptr<Botan::RandomNumberGenerator> kat_rng;
      if(vars.count("Nonce"))
         {
         kat_rng.reset(test_rng(get_req_bin(vars, "Nonce")));
         }

      if(padding == "Raw")
         {
         /*
         Hack for RSA with no padding since sometimes one more bit will fit in but maximum_input_size
         rounds down to nearest byte
         */
         result.test_lte("Input within accepted bounds",
                         plaintext.size(), encryptor->maximum_input_size() + 1);
         }
      else
         {
         result.test_lte("Input within accepted bounds",
                         plaintext.size(), encryptor->maximum_input_size());
         }

      const std::vector<uint8_t> generated_ciphertext =
         encryptor->encrypt(plaintext, kat_rng ? *kat_rng : Test::rng());

      if(enc_provider == "base")
         {
         result.test_eq(enc_provider, "generated ciphertext matches KAT",
                        generated_ciphertext, ciphertext);
         }
      else if(generated_ciphertext != ciphertext)
         {
         for(std::unique_ptr<Botan::PK_Decryptor>& dec : decryptors)
            {
            result.test_eq("decryption of generated ciphertext",
                           dec->decrypt(generated_ciphertext), plaintext);
            }
         }

      }

   return result;
   }
Beispiel #17
0
Test::Result
PK_Signature_Generation_Test::run_one_test(const std::string& pad_hdr, const VarMap& vars)
   {
   const std::vector<uint8_t> message   = get_req_bin(vars, "Msg");
   const std::vector<uint8_t> signature = get_req_bin(vars, "Signature");
   const std::string padding = choose_padding(vars, pad_hdr);

   Test::Result result(algo_name() + "/" + padding + " signature generation");

   std::unique_ptr<Botan::Private_Key> privkey;
   try
      {
      privkey = load_private_key(vars);
      }
   catch(Botan::Lookup_Error& e)
      {
      result.note_missing(e.what());
      return result;
      }

   std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey)));

   std::vector<std::unique_ptr<Botan::PK_Verifier>> verifiers;

   for(auto const& verify_provider : possible_providers(algo_name()))
      {
      std::unique_ptr<Botan::PK_Verifier> verifier;

      try
         {
         verifier.reset(new Botan::PK_Verifier(*pubkey, padding, Botan::IEEE_1363, verify_provider));
         }
      catch(Botan::Lookup_Error&)
         {
         //result.test_note("Skipping verifying with " + verify_provider);
         continue;
         }

      result.test_eq("KAT signature valid", verifier->verify_message(message, signature), true);

      check_invalid_signatures(result, *verifier, message, signature);
      verifiers.push_back(std::move(verifier));
      }

   for(auto const& sign_provider : possible_providers(algo_name()))
      {
      std::unique_ptr<Botan::RandomNumberGenerator> rng;
      if(vars.count("Nonce"))
         {
         rng.reset(test_rng(get_req_bin(vars, "Nonce")));
         }

      std::unique_ptr<Botan::PK_Signer> signer;

      std::vector<uint8_t> generated_signature;

      try
         {
         signer.reset(new Botan::PK_Signer(*privkey, Test::rng(), padding, Botan::IEEE_1363, sign_provider));

         generated_signature = signer->sign_message(message, rng ? *rng : Test::rng());
         }
      catch(Botan::Lookup_Error&)
         {
         //result.test_note("Skipping signing with " + sign_provider);
         continue;
         }

      if(sign_provider == "base")
         {
         result.test_eq("generated signature matches KAT", generated_signature, signature);
         }
      else if(generated_signature != signature)
         {
         for(std::unique_ptr<Botan::PK_Verifier>& verifier : verifiers)
            {
            if(!result.test_eq("generated signature valid",
                               verifier->verify_message(message, generated_signature), true))
               {
               result.test_failure("generated signature", generated_signature);
               }
            }
         }
      }

   return result;
   }