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; }
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; }
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; }
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; }
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; }
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); }
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; }
/* * 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; }
/* * 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; }
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; }
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; } }
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; } }
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); }
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; }
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; }