/* * Null HTTP realm when initializing server */ static void us901_test15(void) { unsigned char *cacerts = NULL; int cacerts_len = 0; BIO *certin, *keyin; X509 *x; EVP_PKEY *priv_key; int rv; EST_CTX *ctx; LOG_FUNC_NM ; /* * Read in the CA certificates */ cacerts_len = read_binary_file(US901_CACERT, &cacerts); CU_ASSERT(cacerts_len > 0); /* * Read the server cert */ certin = BIO_new(BIO_s_file_internal()); rv = BIO_read_filename(certin, US901_SERVER_CERT); CU_ASSERT(rv > 0); x = PEM_read_bio_X509(certin, NULL, NULL, NULL); CU_ASSERT(x != NULL); BIO_free(certin); /* * Read the server key */ keyin = BIO_new(BIO_s_file_internal()); rv = BIO_read_filename(keyin, US901_SERVER_KEY); CU_ASSERT(rv > 0); priv_key = PEM_read_bio_PrivateKey(keyin, NULL, NULL, NULL); CU_ASSERT(priv_key != NULL); BIO_free(keyin); /* * Attempt to init EST server using NULL realm */ est_init_logger(EST_LOG_LVL_INFO, NULL); ctx = est_server_init(cacerts, cacerts_len, cacerts, cacerts_len, EST_CERT_FORMAT_PEM, NULL, x, priv_key); CU_ASSERT(ctx == NULL); X509_free(x); EVP_PKEY_free(priv_key); }
/* * Corrupted CA chain when initializing server */ static void us901_test19(void) { BIO *certin, *keyin; X509 *x; EVP_PKEY *priv_key; int rv; EST_CTX *ctx; LOG_FUNC_NM ; /* * Read the server cert */ certin = BIO_new(BIO_s_file_internal()); rv = BIO_read_filename(certin, US901_SERVER_CERT); CU_ASSERT(rv > 0); x = PEM_read_bio_X509(certin, NULL, NULL, NULL); CU_ASSERT(x != NULL); BIO_free(certin); /* * Read the server key */ keyin = BIO_new(BIO_s_file_internal()); rv = BIO_read_filename(keyin, US901_SERVER_KEY); CU_ASSERT(rv > 0); priv_key = PEM_read_bio_PrivateKey(keyin, NULL, NULL, NULL); CU_ASSERT(priv_key != NULL); BIO_free(keyin); /* * Attempt to init EST server a corrupted CA chain */ est_init_logger(EST_LOG_LVL_INFO, NULL); ctx = est_server_init((unsigned char*) "Bogus CA chain", 14, (unsigned char*) "Bogus CA chain", 14, EST_CERT_FORMAT_PEM, "testrealm", x, priv_key); CU_ASSERT(ctx == NULL); X509_free(x); EVP_PKEY_free(priv_key); }
/* * This is the main entry point into the example EST server. * This routine parses the command line options, reads in the * cert chains, creates an EST context, initializes the HTTP * layer (mongoose), and starts a simple TCP server to accept * incoming EST requests. */ int main (int argc, char **argv) { char c; int i; X509 *x; EVP_PKEY * priv_key; BIO *certin; DH *dh; EST_ERROR rv; int sleep_delay = 0; int retry_period = 300; char vfile[255]; int option_index = 0; pem_password_cb *priv_key_cb = NULL; static struct option long_options[] = { {"srp", 1, NULL, 0}, {"enforce-csr", 0, NULL, 0}, {"token", 1, 0, 0}, {"keypass", 1, 0, 0}, {"keypass_stdin", 1, 0, 0 }, {"keypass_arg", 1, 0, 0 }, {NULL, 0, NULL, 0} }; #ifdef WIN32 InitializeCriticalSection(&enrollment_critical_section); #endif /* Show usage if -h or --help options are specified */ if ((argc == 1) || (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")))) { show_usage_and_exit(); } while ((c = getopt_long(argc, argv, "?fhbwnovr:c:k:m:p:d:lt6", long_options, &option_index)) != -1) { switch (c) { case 0: #if 0 printf("option %s", long_options[option_index].name); if (optarg) { printf(" with arg %s", optarg); } printf("\n"); #endif if (!strncmp(long_options[option_index].name, "srp", strlen("srp"))) { srp = 1; strncpy(vfile, optarg, 255); } if (!strncmp(long_options[option_index].name, "enforce-csr", strlen("enforce-csr"))) { enforce_csr = 1; } if (!strncmp(long_options[option_index].name, "token", strlen("token"))) { http_token_auth = 1; memset(valid_token_value, 0, MAX_AUTH_TOKEN_LEN + 1); strncpy(&(valid_token_value[0]), optarg, MAX_AUTH_TOKEN_LEN); } if (!strncmp(long_options[option_index].name,"keypass_stdin", strlen("keypass_stdin"))) { priv_key_cb = PEM_def_callback; } if (!strncmp(long_options[option_index].name,"keypass_arg", strlen("keypass_arg"))) { strncpy(priv_key_pwd, optarg, MAX_PWD_LEN); priv_key_cb = string_password_cb; } break; case 'm': manual_enroll = 1; retry_period = atoi(optarg); break; case 'h': http_digest_auth = 1; break; case 'b': http_basic_auth = 1; break; case 'w': write_csr = 1; break; case 'n': http_auth_disable = 1; break; case 'o': disable_forced_http_auth = 1; break; case 'v': verbose = 1; break; case 'l': crl = 1; break; case 't': pop = 1; break; case '6': v6 = 1; break; #ifndef DISABLE_PTHREADS case 'd': sleep_delay = atoi(optarg); break; #endif case 'p': tcp_port = atoi(optarg); break; case 'c': strncpy(certfile, optarg, EST_MAX_FILE_LEN); break; case 'k': strncpy(keyfile, optarg, EST_MAX_FILE_LEN); break; case 'r': if (strnlen(optarg, MAX_REALM_LEN+1) > MAX_REALM_LEN) { printf("\nRealm value is too large. Max is 32 characters\n"); exit(1); } strncpy(realm, optarg, MAX_REALM_LEN); break; case 'f': /* turn FIPS on if user requested it * and exit if failure. */ set_fips_return = FIPS_mode_set(1); if (set_fips_return != 1) { set_fips_error = ERR_get_error(); printf("\nERROR WHILE SETTING FIPS MODE ON exiting ....\n"); exit(1); } else { printf("\nRunning EST Sample Server with FIPS MODE = ON !\n"); } ; break; default: show_usage_and_exit(); break; } } argc -= optind; argv += optind; if (verbose) { print_version(stdout); } if (getenv("EST_CSR_ATTR")) { printf("\nUsing CSR Attributes: %s", getenv("EST_CSR_ATTR")); } if (!getenv("EST_CACERTS_RESP")) { printf("\nEST_CACERTS_RESP file not set, set this env variable to resolve"); exit(1); } if (!getenv("EST_TRUSTED_CERTS")) { printf("\nEST_TRUSTED_CERTS file not set, set this env variable to resolve"); exit(1); } /* * Read in the CA certificates */ cacerts_len = read_binary_file(getenv("EST_CACERTS_RESP"), &cacerts_raw); if (cacerts_len <= 0) { printf("\nEST_CACERTS_RESP file could not be read\n"); exit(1); } /* * Read in the trusted CA certificates for the local TLS context */ if (getenv("EST_TRUSTED_CERTS")) { trustcerts_len = read_binary_file(getenv("EST_TRUSTED_CERTS"), &trustcerts); if (trustcerts_len <= 0) { printf("\nEST_TRUSTED_CERTS file could not be read\n"); exit(1); } } est_apps_startup(); /* * Read in the local server certificate */ certin = BIO_new(BIO_s_file_internal()); if (BIO_read_filename(certin, certfile) <= 0) { printf("\nUnable to read server certificate file %s\n", certfile); exit(1); } /* * This reads the file, which is expected to be PEM encoded. If you're using * DER encoded certs, you would invoke d2i_X509_bio() instead. */ x = PEM_read_bio_X509(certin, NULL, NULL, NULL); if (x == NULL) { printf("\nError while reading PEM encoded server certificate file %s\n", certfile); exit(1); } BIO_free(certin); /* * Read in the server's private key */ priv_key = read_private_key(keyfile, priv_key_cb); if (priv_key == NULL) { printf("\nError while reading PEM encoded server private key file %s\n", keyfile); ERR_print_errors_fp(stderr); exit(1); } bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (!bio_err) { printf("\nBIO not working\n"); exit(1); } if (verbose) { est_init_logger(EST_LOG_LVL_INFO, NULL); est_enable_backtrace(1); } else { est_init_logger(EST_LOG_LVL_ERR, NULL); } ectx = est_server_init(trustcerts, trustcerts_len, cacerts_raw, cacerts_len, EST_CERT_FORMAT_PEM, realm, x, priv_key); if (!ectx) { printf("\nUnable to initialize EST context. Aborting!!!\n"); exit(1); } est_set_ex_data(ectx, &test_app_data); if (enforce_csr) { est_server_enforce_csrattr(ectx); } /* * Change the retry-after period. This is not * necessary, it's only shown here as an example. */ if (verbose) printf("\nRetry period being set to: %d \n", retry_period); est_server_set_retry_period(ectx, retry_period); if (crl) { est_enable_crl(ectx); } if (!pop) { if (verbose) printf("\nDisabling PoP check"); est_server_disable_pop(ectx); } if (srp) { srp_db = SRP_VBASE_new(NULL); if (!srp_db) { printf("\nUnable allocate SRP verifier database. Aborting!!!\n"); exit(1); } if (SRP_VBASE_init(srp_db, vfile) != SRP_NO_ERROR) { printf("\nUnable initialize SRP verifier database. Aborting!!!\n"); exit(1); } if (est_server_enable_srp(ectx, &process_ssl_srp_auth)) { printf("\nUnable to enable SRP. Aborting!!!\n"); exit(1); } } if (est_set_ca_enroll_cb(ectx, &process_pkcs10_enrollment)) { printf( "\nUnable to set EST pkcs10 enrollment callback. Aborting!!!\n"); exit(1); } /* * We use the same handler for re-enrollment. Our little toy * CA doesn't do anything special for re-enrollment. A real * CA would need to implement the requirements in section * 4.2 of the EST draft. */ if (est_set_ca_reenroll_cb(ectx, &process_pkcs10_enrollment)) { printf( "\nUnable to set EST pkcs10 enrollment callback. Aborting!!!\n"); exit(1); } if (est_set_csr_cb(ectx, &process_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } if (!http_auth_disable) { if (est_set_http_auth_cb(ectx, &process_http_auth)) { printf("\nUnable to set EST HTTP AUTH callback. Aborting!!!\n"); exit(1); } } if (disable_forced_http_auth) { if (verbose) printf( "\nDisabling HTTP authentication when TLS client auth succeeds\n"); if (est_set_http_auth_required(ectx, HTTP_AUTH_NOT_REQUIRED)) { printf("\nUnable to disable required HTTP auth. Aborting!!!\n"); exit(1); } } if (http_digest_auth) { MD5_CTX c; int len; static unsigned char ha1_input_buf[32*3+2]; unsigned char md[17]; int i; rv = est_server_set_auth_mode(ectx, AUTH_DIGEST); if (rv != EST_ERR_NONE) { printf( "\nUnable to enable HTTP digest authentication. Aborting!!!\n"); exit(1); } /* * Cache away the realm value and build the HA1 */ strncpy(digest_user[1], realm, MAX_REALM_LEN); len = sprintf((char *)ha1_input_buf, "%s:%s:%s", "estuser", realm, "estpwd"); MD5_Init(&c); MD5_Update(&c, ha1_input_buf, len); MD5_Final((unsigned char *)md, &c); printf("\nDigest HA1 value = "); memset(digest_user[2], 0, 32); for(i = 0; i < 16; i++){ sprintf(&(digest_user[2][i*2]),"%.2x", (unsigned char) md[i]); printf("%c%c", digest_user[2][i*2], digest_user[2][i*2+1]); } printf("\n"); } if (http_basic_auth) { rv = est_server_set_auth_mode(ectx, AUTH_BASIC); if (rv != EST_ERR_NONE) { printf( "\nUnable to enable HTTP basic authentication. Aborting!!!\n"); exit(1); } } if (http_token_auth) { rv = est_server_set_auth_mode(ectx, AUTH_TOKEN); if (rv != EST_ERR_NONE) { printf( "\nUnable to enable HTTP token authentication. Aborting!!!\n"); exit(1); } } /* * Set DH parameters for TLS */ dh = get_dh1024dsa(); if (dh) { est_server_set_dh_parms(ectx, dh); } DH_free(dh); /* * Install thread locking mechanism for OpenSSL */ mutex_buf = malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); if (!mutex_buf) { printf("Cannot allocate mutexes"); exit(1); } for (i = 0; i < CRYPTO_num_locks(); i++) MUTEX_SETUP(mutex_buf[i]); CRYPTO_set_id_callback(id_function); CRYPTO_set_locking_callback(locking_function); printf("\nLaunching EST server...\n"); rv = est_server_start(ectx); if (rv != EST_ERR_NONE) { printf("\nFailed to init mg (rv=%d)\n", rv); exit(1); } /* * Start the simple server, which opens a TCP * socket, waits for incoming connections, and * invokes the EST handler for each connection. */ start_simple_server(ectx, tcp_port, sleep_delay, v6); cleanup(); EVP_PKEY_free(priv_key); X509_free(x); return 0; }
/* * est_server_set_auth_mode() - unit test * * First, Test the parameters of est_server_set_auth_mode() */ static void us1864_test1 (void) { unsigned char *cacerts = NULL; int cacerts_len = 0; BIO *certin, *keyin; X509 *x; EVP_PKEY *priv_key; int rv; EST_CTX *ctx; EST_ERROR est_rv; LOG_FUNC_NM; /* * Read in the CA certificates */ cacerts_len = read_binary_file(US1864_CACERT, &cacerts); CU_ASSERT(cacerts_len > 0); /* * Read the server cert */ certin = BIO_new(BIO_s_file_internal()); rv = BIO_read_filename(certin, US1864_SERVER_CERT); CU_ASSERT(rv > 0); x = PEM_read_bio_X509(certin, NULL, NULL, NULL); CU_ASSERT(x != NULL); BIO_free(certin); /* * Read the server key */ keyin = BIO_new(BIO_s_file_internal()); rv = BIO_read_filename(keyin, US1864_SERVER_KEY); CU_ASSERT(rv > 0); priv_key = PEM_read_bio_PrivateKey(keyin, NULL, NULL, NULL); CU_ASSERT(priv_key != NULL); BIO_free(keyin); /* * init EST in server mode */ est_init_logger(EST_LOG_LVL_INFO, NULL); ctx = est_server_init(cacerts, cacerts_len, cacerts, cacerts_len, EST_CERT_FORMAT_PEM, "testrealm", x, priv_key); CU_ASSERT(ctx != NULL); est_rv = est_server_set_auth_mode(ctx, AUTH_NONE); CU_ASSERT(est_rv == EST_ERR_BAD_MODE); est_rv = est_server_set_auth_mode(ctx, AUTH_BASIC); CU_ASSERT(est_rv == EST_ERR_NONE); est_rv = est_server_set_auth_mode(ctx, AUTH_DIGEST); CU_ASSERT(est_rv == EST_ERR_NONE); est_rv = est_server_set_auth_mode(ctx, AUTH_TOKEN); CU_ASSERT(est_rv == EST_ERR_NONE); est_rv = est_server_set_auth_mode(ctx, 0xffffffff); CU_ASSERT(est_rv == EST_ERR_BAD_MODE); #if 0 //TODO: FIPS mode is not a concern /* * Make sure we don't allow DIGEST mode when in FIPS mode */ FIPS_mode_set(1); est_rv = est_server_set_auth_mode(ctx, AUTH_DIGEST); CU_ASSERT(est_rv == EST_ERR_BAD_MODE); FIPS_mode_set(0); #endif X509_free(x); EVP_PKEY_free(priv_key); est_destroy(ctx); }