ENVELOP_API int env_init(IN const char * cert,IN const char * key) { //初始化Openssl do { CRYPTO_malloc_init(); OpenSSL_add_all_algorithms(); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); ERR_load_PEM_strings();//TaoNote ,如果不调这个函数,则在读读取PEM时会异常 ERR_load_crypto_strings(); } while(0); //检查证书文件是否可用 if(cert != NULL) { if(g_pub_key != NULL) EVP_PKEY_free(g_pub_key); g_pub_key = read_pub_key(cert); if(!g_pub_key) return ERR_ENV_CERT_INVALID; g_pub_key_size = EVP_PKEY_size(g_pub_key); } //检查私钥文件是否可用 if(g_prv_key != NULL) EVP_PKEY_free(g_prv_key); g_prv_key = read_private_key(key); if (!g_prv_key) return ERR_ENV_KEY_INVALID; return 0; }
ENVELOP_API int env_check(IN const char * cert,IN const char * key) { EVP_PKEY * pub_key = NULL; EVP_PKEY * prv_key = NULL; pub_key = read_pub_key(cert); if(!pub_key) return ERR_ENV_CERT_INVALID; EVP_PKEY_free(pub_key); prv_key = read_private_key(key); if(!prv_key) return ERR_ENV_KEY_INVALID; EVP_PKEY_free(prv_key); return 0; }
/* * 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; }
int main (int argc, char **argv) { signed char c; int set_fips_return = 0; char file_name[MAX_FILENAME_LEN]; BIO *keyin; BIO *certin; static struct option long_options[] = { { "trustanchor", 1, 0, 0 }, { "srp", 0, 0, 0 }, { "srp-user", 1, 0, 0 }, { "srp-password", 1, 0, 0 }, { "auth-token", 1, 0, 0 }, { "common-name", 1, 0, 0 }, { "pem-output", 0, 0, 0 }, { NULL, 0, NULL, 0 } }; int option_index = 0; int trustanchor = 1; /* default to require a trust anchor */ char *trustanchor_file = NULL; est_http_uid[0] = 0x0; est_http_pwd[0] = 0x0; /* * Set the default common name to put into the Subject field */ strncpy(subj_cn, "127.0.0.1", MAX_CN); memset(csr_file, 0, 1); memset(priv_key_file, 0, 1); memset(client_key_file, 0, 1); memset(client_cert_file, 0, 1); memset(out_dir, 0, 1); while ((c = getopt_long(argc, argv, "?zfvagerx:y:k:s:p:o:c:w:u:h:", 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, "trustanchor", strlen("trustanchor"))) { if (!strncmp(optarg, "no", strlen("no"))) { trustanchor = 0; } else { trustanchor_file = optarg; } } if (!strncmp(long_options[option_index].name, "srp", strlen("srp"))) { srp = 1; } if (!strncmp(long_options[option_index].name, "srp-user", strlen("srp-user"))) { strncpy(est_srp_uid, optarg, MAX_UID_LEN); } if (!strncmp(long_options[option_index].name, "srp-password", strlen("srp-password"))) { strncpy(est_srp_pwd, optarg, MAX_PWD_LEN); } if (!strncmp(long_options[option_index].name,"auth-token", strlen("auth-token"))) { strncpy(est_auth_token, optarg, MAX_AUTH_TOKEN_LEN); token_auth_mode = 1; } if (!strncmp(long_options[option_index].name, "common-name", strlen("common-name"))) { strncpy(subj_cn, optarg, MAX_CN); } if (!strncmp(long_options[option_index].name, "pem-output", strlen("pem-output"))) { pem_out = 1; } break; case 'v': verbose = 1; break; case 'z': force_pop = 1; break; case 'a': getcsr = 1; break; case 'g': getcert = 1; break; case 'e': enroll = 1; break; case 'r': reenroll = 1; break; case 'u': strncpy(est_http_uid, optarg, MAX_UID_LEN); break; case 'h': strncpy(est_http_pwd, optarg, MAX_PWD_LEN); break; case 's': strncpy(est_server, optarg, MAX_SERVER_LEN); break; case 'x': strncpy(priv_key_file, optarg, MAX_FILENAME_LEN); break; case 'y': strncpy(csr_file, optarg, MAX_FILENAME_LEN); break; case 'k': strncpy(client_key_file, optarg, MAX_FILENAME_LEN); break; case 'c': strncpy(client_cert_file, optarg, MAX_FILENAME_LEN); break; case 'o': strncpy(out_dir, optarg, MAX_FILENAME_LEN); break; case 'p': est_port = atoi(optarg); break; case 'f': /* Turn FIPS on if requested and exit if failure */ set_fips_return = FIPS_mode_set(1); if (!set_fips_return) { printf("\nERROR setting FIPS MODE ON ...\n"); ERR_load_crypto_strings(); ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE)); exit(1); } else { printf("\nRunning EST Sample Client with FIPS MODE = ON\n"); }; break; case 'w': read_timeout = atoi(optarg); if (read_timeout > EST_SSL_READ_TIMEOUT_MAX) { printf("\nMaxium number of seconds to wait is %d, ", EST_SSL_READ_TIMEOUT_MAX); printf("please use a lower value with the -w option\n"); exit(1); } break; default: show_usage_and_exit(); break; } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) { printf("%s ", argv[optind++]); } printf("\n"); } argc -= optind; argv += optind; if (est_http_uid[0] && !est_http_pwd[0]) { printf("Error: The password for HTTP authentication must be specified when the HTTP user name is set.\n"); exit(1); } if (csr_file[0] && getcsr) { printf("\nError: The -a option (CSR attributes) does not make sense with a pre-defined CSR\n"); exit(1); } if (csr_file[0] && priv_key_file[0]) { printf("\nError: The -x option (private key for CSR) does not make sense with a pre-defined CSR\n"); exit(1); } if (csr_file[0] && force_pop) { printf("\nError: The -z option (PoP) does not make sense with a pre-defined CSR\n"); exit(1); } if (reenroll & csr_file[0]) { printf("\nError: The -y option (predefined CSRs) does not make sense for re-enrollment\n"); exit(1); } if (verbose) { print_version(); printf("\nUsing EST server %s:%d", est_server, est_port); if (csr_file [0]) { printf("\nUsing CSR file %s", csr_file); } if (priv_key_file [0]) { printf("\nUsing identity private key file %s", priv_key_file); } if (client_cert_file[0]) { printf("\nUsing identity client cert file %s", client_cert_file); } if (client_key_file [0]) { printf("\nUsing identity private key file %s", client_key_file); } } if (enroll && reenroll) { printf("\nThe enroll and reenroll operations can not be used together\n"); exit(1); } if (!out_dir[0]) { printf("\nOutput directory must be specified with -o option\n"); exit(1); } if (trustanchor) { if (!trustanchor_file) { /* * Get the trust anchor filename from the environment var */ if (!getenv("EST_OPENSSL_CACERT")) { printf("\nCACERT file not set, set EST_OPENSSL_CACERT to resolve"); exit(1); } trustanchor_file = getenv("EST_OPENSSL_CACERT"); } /* * Read in the CA certificates */ cacerts_len = read_binary_file(trustanchor_file, &cacerts); if (cacerts_len <= 0) { printf("\nCACERT file could not be read\n"); exit(1); } } /* * Read in the current client certificate */ if (client_cert_file[0]) { certin = BIO_new(BIO_s_file_internal()); if (BIO_read_filename(certin, client_cert_file) <= 0) { printf("\nUnable to read client certificate file %s\n", client_cert_file); 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. */ client_cert = PEM_read_bio_X509(certin, NULL, NULL, NULL); if (client_cert == NULL) { printf("\nError while reading PEM encoded client certificate file %s\n", client_cert_file); exit(1); } BIO_free(certin); } /* * Read in the client's private key */ if (client_key_file[0]) { keyin = BIO_new(BIO_s_file_internal()); if (BIO_read_filename(keyin, client_key_file) <= 0) { printf("\nUnable to read client private key file %s\n", client_key_file); exit(1); } /* * This reads in the private key file, which is expected to be a PEM * encoded private key. If using DER encoding, you would invoke * d2i_PrivateKey_bio() instead. */ client_priv_key = PEM_read_bio_PrivateKey(keyin, NULL, NULL, NULL); if (client_priv_key == NULL) { printf("\nError while reading PEM encoded private key file %s\n", client_key_file); ERR_print_errors_fp(stderr); exit(1); } BIO_free(keyin); } est_apps_startup(); #if DEBUG_OSSL_LEAKS CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #endif if (verbose) { est_init_logger(EST_LOG_LVL_INFO, &test_logger_stdout); est_enable_backtrace(1); } else { est_init_logger(EST_LOG_LVL_ERR, &test_logger_stdout); } if (!priv_key_file[0] && enroll && !csr_file[0]) { printf("\nA private key is required for enrolling. Creating a new RSA key pair since you didn't provide a key using the -x option."); /* * Create a private key that will be used for the * enroll operation. */ new_pkey = generate_private_key(&new_pkey_len); snprintf(file_name, MAX_FILENAME_LEN, "%s/newkey.pem", out_dir); write_binary_file(file_name, new_pkey, new_pkey_len); free(new_pkey); /* * prepare to read it back in to an EVP_PKEY struct */ strncpy(priv_key_file, file_name, MAX_FILENAME_LEN); } if (enroll && !csr_file[0]) { /* Read in the private key file */ priv_key = read_private_key(priv_key_file); } do_operation(); if (priv_key) { EVP_PKEY_free(priv_key); } if (client_priv_key) { EVP_PKEY_free(client_priv_key); } if (client_cert) { X509_free(client_cert); } free(cacerts); if (c_cert_len) { free(c_cert); } if (c_key_len) { free(c_key); } est_apps_shutdown(); #if DEBUG_OSSL_LEAKS BIO *bio_err; bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); CRYPTO_mem_leaks(bio_err); BIO_free(bio_err); #endif printf("\n"); return 0; }
/* * Test1 - exercise the server side variations triggered * by est_client_get_csrattrs() */ static void us895_test1 (void) { EST_CTX *ctx; unsigned char *pkey = NULL; unsigned char *cacerts = NULL; int cacerts_len = 0; EST_ERROR rc = EST_ERR_NONE; EVP_PKEY * priv_key; int csr_len; unsigned char *csr_data = NULL; SLEEP(1); LOG_FUNC_NM ; /* * Read in the CA certificates */ cacerts_len = read_binary_file(SERVER_UT_CACERT, &cacerts); CU_ASSERT(cacerts_len > 0); /* * Read in the private key file */ priv_key = read_private_key(SERVER_UT_PUBKEY); if (priv_key == NULL) { printf("\nError while reading private key file %s\n", SERVER_UT_PUBKEY); return; } ctx = est_client_init( cacerts, cacerts_len, EST_CERT_FORMAT_PEM, proxy_manual_cert_verify); CU_ASSERT(ctx != NULL); rc = est_client_set_auth(ctx, "", "", NULL, priv_key); CU_ASSERT(rc == EST_ERR_NONE); est_client_set_server(ctx, US895_SERVER_IP, US895_PROXY_PORT, NULL); /* clear callback */ if (est_set_csr_cb(ectx, NULL)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* clear csrattrs */ rc = est_server_init_csrattrs(ectx, NULL, 0); CU_ASSERT(rc == EST_ERR_NONE); /* should get 204 with no data */ rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == 0); CU_ASSERT(csr_data == NULL); /* Real base64 string - should pass */ rc = est_server_init_csrattrs(ectx, TEST_ATTR_POP, strlen(TEST_ATTR_POP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_POP)); CU_ASSERT(strncmp(TEST_ATTR_POP, (const char *) csr_data, csr_len) == 0); if (est_set_csr_cb(ectx, &handle_short_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* callback should supersede init csrattrs */ rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == 0); if (est_set_csr_cb(ectx, &handle_corrupt_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* callback should supersede init csrattrs */ rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == 0); if (est_set_csr_cb(ectx, &handle_long_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* callback should supersede init csrattrs */ rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == 0); if (est_set_csr_cb(ectx, &handle_correct_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* callback should supersede init csrattrs */ rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR1)); CU_ASSERT(strncmp(TEST_ATTR1, (const char *) csr_data, csr_len) == 0); /* clear csrattrs */ rc = est_server_init_csrattrs(ectx, NULL, 0); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR1)); CU_ASSERT(strncmp(TEST_ATTR1, (const char *) csr_data, csr_len) == 0); /* clear callback */ if (est_set_csr_cb(ectx, NULL)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* Setting the smallest base64 size */ rc = est_server_init_csrattrs(ectx, TEST_ATTR2, strlen(TEST_ATTR2)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR2)); CU_ASSERT(strncmp(TEST_ATTR2, (const char *) csr_data, csr_len) == 0); rc = est_server_init_csrattrs(ectx, TEST_ATTR3, strlen(TEST_ATTR3)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR3)); CU_ASSERT(strncmp(TEST_ATTR3, (const char *) csr_data, csr_len) == 0); /* clear csrattrs */ rc = est_server_init_csrattrs(ectx, NULL, 0); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == 0); rc = est_server_init_csrattrs( ectx, TEST_1024_NOPOP, strlen(TEST_1024_NOPOP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_1024_NOPOP)); CU_ASSERT(strncmp(TEST_1024_NOPOP, (const char *) csr_data, csr_len) == 0); /* Enable PoP and test responses with PoP added */ st_enable_pop(); rc = est_server_init_csrattrs(ectx, TEST_ATTR_POP, strlen(TEST_ATTR_POP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_data != NULL); CU_ASSERT(csr_len = 20); CU_ASSERT(strncmp(TEST_ATTR_POP, (const char *) csr_data, csr_len) == 0); rc = est_server_init_csrattrs( ectx, TEST_1024_NOPOP, strlen(TEST_1024_NOPOP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_1024_POP)); CU_ASSERT(strncmp(TEST_1024_POP, (const char *) csr_data, csr_len) == 0); /* Setting the size 122 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR4_122, strlen(TEST_ATTR4_122)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR4_122POP)); CU_ASSERT( strncmp(TEST_ATTR4_122POP, (const char *) csr_data, csr_len) == 0); /* Setting the size 117 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR5_117, strlen(TEST_ATTR5_117)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR5_117POP)); CU_ASSERT( strncmp(TEST_ATTR5_117POP, (const char *) csr_data, csr_len) == 0); /* Real base64 string needs PoP added - should pass */ rc = est_server_init_csrattrs( ectx, TEST_ATTR_NOPOP, strlen(TEST_ATTR_NOPOP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_NOPOPPOP)); CU_ASSERT( strncmp(TEST_ATTR_NOPOPPOP, (const char *) csr_data, csr_len) == 0); /* Not a real base64 string - should fail */ rc = est_server_init_csrattrs(ectx, "US900 test1", 11); CU_ASSERT(rc != EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_POP)); CU_ASSERT(strncmp(TEST_ATTR_POP, (const char *) csr_data, csr_len) == 0); /* Setting the smallest size */ rc = est_server_init_csrattrs(ectx, TEST_ATTR2, strlen(TEST_ATTR2)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR2_POP)); CU_ASSERT(strncmp(TEST_ATTR2_POP, (const char *) csr_data, csr_len) == 0); /* Setting the size 116 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR6_116, strlen(TEST_ATTR6_116)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); /* Setting the size 244 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR_244, strlen(TEST_ATTR_244)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); /* Setting the size 245 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR_245, strlen(TEST_ATTR_245)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); /* Setting the size 250 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR_250, strlen(TEST_ATTR_250)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_250POP)); CU_ASSERT(strncmp(TEST_ATTR_250POP, (const char *) csr_data, csr_len) == 0); if (est_set_csr_cb(ectx, &handle_correct_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR1)); CU_ASSERT(strncmp(TEST_ATTR1, (const char *) csr_data, csr_len) == 0); if (est_set_csr_cb(ectx, &handle_nopop_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_NOPOPPOP)); CU_ASSERT( strncmp(TEST_ATTR_NOPOPPOP, (const char *) csr_data, csr_len) == 0); if (est_set_csr_cb(ectx, &handle_empty_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR2_POP)); CU_ASSERT(strncmp(TEST_ATTR2_POP, (const char *) csr_data, csr_len) == 0); /* disable PoP */ st_disable_pop(); /* clear callback */ if (est_set_csr_cb(ectx, NULL)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* Real base64 string PoP should not be added - should pass */ rc = est_server_init_csrattrs( ectx, TEST_ATTR_NOPOP, strlen(TEST_ATTR_NOPOP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_NOPOP)); CU_ASSERT(strncmp(TEST_ATTR_NOPOP, (const char *) csr_data, csr_len) == 0); /* All ASN.1 types supported by CiscoSSL */ rc = est_server_init_csrattrs(ectx, TEST_ALL_ATTR, strlen(TEST_ALL_ATTR)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ALL_ATTR)); CU_ASSERT(strncmp(TEST_ALL_ATTR, (const char *) csr_data, csr_len) == 0); if (ctx) { est_destroy(ctx); } if (cacerts) { free(cacerts); } if (pkey) { free(pkey); } }
/* * Test2 - exercise the response variations triggered * by est_client_get_csrattrs() */ static void us896_test2(void) { EST_CTX *ctx; unsigned char *pkey = NULL; unsigned char *cacerts = NULL; int cacerts_len = 0; EST_ERROR rc = EST_ERR_NONE; unsigned char *retrieved_cacerts = NULL; int retrieved_cacerts_len = 0; EVP_PKEY *priv_key; SLEEP(1); LOG_FUNC_NM ; /* * Read in the CA certificates */ cacerts_len = read_binary_file(CLIENT_UT_CACERT, &cacerts); CU_ASSERT(cacerts_len > 0); /* * Read in the private key file */ priv_key = read_private_key(CLIENT_UT_PUBKEY); if (priv_key == NULL) { printf("\nError while reading private key file %s\n", CLIENT_UT_PUBKEY); return; } ctx = est_client_init(cacerts, cacerts_len, EST_CERT_FORMAT_PEM, client_manual_cert_verify); CU_ASSERT(ctx != NULL); rc = est_client_set_auth(ctx, "", "", NULL, priv_key); CU_ASSERT(rc == EST_ERR_NONE); est_client_set_server(ctx, US896_SERVER_IP, US896_SERVER_PORT, NULL); /* * issue the get ca certs request */ rc = est_client_get_cacerts(ctx, &retrieved_cacerts_len); /* * should be successful, and should have obtained a valid buffer * containing the CA certs */ CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(retrieved_cacerts_len > 0); retrieved_cacerts = malloc(retrieved_cacerts_len); rc = est_client_copy_cacerts(ctx, retrieved_cacerts); /* * output the retrieved ca certs and compare to what they should be */ if (retrieved_cacerts) { printf("\nRetrieved CA Certs buffer:\n %s\n", retrieved_cacerts); printf("Retrieved CA certs buffer length: %d\n", retrieved_cacerts_len); } free(retrieved_cacerts); /* * All of these are negative tests and require that code in the * EST server is modified such that it will allow bad/corrupted * attributes to be initialized so they can be sent to the client. */ #ifdef NEGATIVE_UNIT_TEST unsigned char *csr_data; int csr_len; /* clear callback */ if (est_set_csr_cb(ectx, NULL)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } rc = est_server_init_csrattrs(ectx, TEST_CORRUPT_ATTR1, strlen(TEST_CORRUPT_ATTR1)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc != EST_ERR_NONE); CU_ASSERT(csr_len == 0); CU_ASSERT(csr_data == NULL); rc = est_server_init_csrattrs(ectx, TEST_CORRUPT_ATTR2, strlen(TEST_CORRUPT_ATTR2)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc != EST_ERR_NONE); CU_ASSERT(csr_len == 0); CU_ASSERT(csr_data == NULL); rc = est_server_init_csrattrs(ectx, TEST_SHORT_ATTR, strlen(TEST_SHORT_ATTR)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc != EST_ERR_NONE); CU_ASSERT(csr_len == 0); CU_ASSERT(csr_data == NULL); rc = est_server_init_csrattrs(ectx, TEST_LONG_ATTR, strlen(TEST_LONG_ATTR)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc != EST_ERR_NONE); CU_ASSERT(csr_len == 0); CU_ASSERT(csr_data == NULL); #endif if (ctx) { est_destroy(ctx); } if (cacerts) { free(cacerts); } if (pkey) { free(pkey); } }
/* * Test2 - exercise the server side variations triggered * by est_client_get_csrattrs() */ static void us900_test2 (void) { EST_CTX *ctx; unsigned char *pkey = NULL; unsigned char *cacerts = NULL; int cacerts_len = 0; EST_ERROR rc = EST_ERR_NONE; unsigned char *retrieved_cacerts = NULL; int retrieved_cacerts_len = 0; EVP_PKEY *priv_key; int csr_len; unsigned char *csr_data = NULL; sleep(1); LOG_FUNC_NM; /* * Read in the CA certificates */ cacerts_len = read_binary_file(CLIENT_UT_CACERT, &cacerts); CU_ASSERT(cacerts_len > 0); /* * Read in the private key file */ priv_key = read_private_key(CLIENT_UT_PUBKEY); if (priv_key == NULL) { printf("\nError while reading private key file %s\n", CLIENT_UT_PUBKEY); return; } ctx = est_client_init(cacerts, cacerts_len, EST_CERT_FORMAT_PEM, client_manual_cert_verify); CU_ASSERT(ctx != NULL); rc = est_client_set_auth(ctx, "", "", NULL, priv_key); CU_ASSERT(rc == EST_ERR_NONE); est_client_set_server(ctx, US900_SERVER_IP, US900_SERVER_PORT); /* * issue the get ca certs request */ rc = est_client_get_cacerts(ctx, &retrieved_cacerts_len); /* * should be successful, and should have obtained a valid buffer * containing the CA certs */ CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(retrieved_cacerts_len > 0); retrieved_cacerts = malloc(retrieved_cacerts_len); rc = est_client_copy_cacerts(ctx, retrieved_cacerts); /* * output the retrieved ca certs and compare to what they should be */ if (retrieved_cacerts) { printf("\nRetrieved CA Certs buffer:\n %.*s\n", retrieved_cacerts_len, retrieved_cacerts); printf("Retrieved CA certs buffer length: %d\n", retrieved_cacerts_len); } free(retrieved_cacerts); /* clear callback */ if (est_set_csr_cb(ectx, NULL)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* clear csrattrs */ rc = est_server_init_csrattrs(ectx, NULL, 0); CU_ASSERT(rc == EST_ERR_NONE); /* should get 204 with no data */ rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == 0); CU_ASSERT(csr_data == NULL); /* Real base64 string - should pass */ rc = est_server_init_csrattrs(ectx, TEST_ATTR_POP, strlen(TEST_ATTR_POP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_POP)); CU_ASSERT(strncmp(TEST_ATTR_POP, (const char *)csr_data, csr_len) == 0); if (est_set_csr_cb(ectx, &handle_corrupt_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* callback should supersede init csrattrs */ rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == 0); if (est_set_csr_cb(ectx, &handle_short_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* callback should supersede init csrattrs */ rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == 0); if (est_set_csr_cb(ectx, &handle_long_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* callback should supersede init csrattrs */ rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == 0); if (est_set_csr_cb(ectx, &handle_correct_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* callback should supersede init csrattrs */ rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR1)); CU_ASSERT(strncmp(TEST_ATTR1, (const char *)csr_data, csr_len) == 0); /* clear csrattrs */ rc = est_server_init_csrattrs(ectx, NULL, 0); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR1)); CU_ASSERT(strncmp(TEST_ATTR1, (const char *)csr_data, csr_len) == 0); /* clear callback */ if (est_set_csr_cb(ectx, NULL)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* Setting the smallest size */ rc = est_server_init_csrattrs(ectx, TEST_ATTR2, strlen(TEST_ATTR2)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR2)); CU_ASSERT(strncmp(TEST_ATTR2, (const char *)csr_data, csr_len) == 0); rc = est_server_init_csrattrs(ectx, TEST_ATTR3, strlen(TEST_ATTR3)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR3)); CU_ASSERT(strncmp(TEST_ATTR3, (const char *)csr_data, csr_len) == 0); /* clear csrattrs */ rc = est_server_init_csrattrs(ectx, NULL, 0); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == 0); rc = est_server_init_csrattrs(ectx, TEST_1024_NOPOP, strlen(TEST_1024_NOPOP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_1024_NOPOP)); CU_ASSERT(strncmp(TEST_1024_NOPOP, (const char *)csr_data, csr_len) == 0); /* Enable PoP and test responses with PoP added */ st_enable_pop(); rc = est_server_init_csrattrs(ectx, TEST_ATTR_POP, strlen(TEST_ATTR_POP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_data != NULL); CU_ASSERT(csr_len = 20); CU_ASSERT(strncmp(TEST_ATTR_POP, (const char *)csr_data, csr_len) == 0); rc = est_server_init_csrattrs(ectx, TEST_1024_NOPOP, strlen(TEST_1024_NOPOP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_1024_POP)); CU_ASSERT(strncmp(TEST_1024_POP, (const char *)csr_data, csr_len) == 0); /* Setting the size 122 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR4_122, strlen(TEST_ATTR4_122)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR4_122POP)); CU_ASSERT(strncmp(TEST_ATTR4_122POP, (const char *)csr_data, csr_len) == 0); /* Setting the size 117 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR5_117, strlen(TEST_ATTR5_117)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR5_117POP)); CU_ASSERT(strncmp(TEST_ATTR5_117POP, (const char *)csr_data, csr_len) == 0); /* Real base64 string needs PoP added - should pass */ rc = est_server_init_csrattrs(ectx, TEST_ATTR_NOPOP, strlen(TEST_ATTR_NOPOP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_NOPOPPOP)); CU_ASSERT(strncmp(TEST_ATTR_NOPOPPOP, (const char *)csr_data, csr_len) == 0); /* Not a real base64 string - should fail */ rc = est_server_init_csrattrs(ectx, "US900 test1", 11); CU_ASSERT(rc != EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_POP)); CU_ASSERT(strncmp(TEST_ATTR_POP, (const char *)csr_data, csr_len) == 0); /* Setting the smallest size */ rc = est_server_init_csrattrs(ectx, TEST_ATTR2, strlen(TEST_ATTR2)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR2_POP)); CU_ASSERT(strncmp(TEST_ATTR2_POP, (const char *)csr_data, csr_len) == 0); /* Setting the size 116 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR6_116, strlen(TEST_ATTR6_116)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); /* Setting the size 244 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR_244, strlen(TEST_ATTR_244)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); /* Setting the size 245 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR_245, strlen(TEST_ATTR_245)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); /* Setting the size 250 */ rc = est_server_init_csrattrs(ectx, TEST_ATTR_250, strlen(TEST_ATTR_250)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_250POP)); CU_ASSERT(strncmp(TEST_ATTR_250POP, (const char *)csr_data, csr_len) == 0); if (est_set_csr_cb(ectx, &handle_correct_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR1)); CU_ASSERT(strncmp(TEST_ATTR1, (const char *)csr_data, csr_len) == 0); if (est_set_csr_cb(ectx, &handle_nopop_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_NOPOPPOP)); CU_ASSERT(strncmp(TEST_ATTR_NOPOPPOP, (const char *)csr_data, csr_len) == 0); if (est_set_csr_cb(ectx, &handle_empty_csrattrs_request)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR2_POP)); CU_ASSERT(strncmp(TEST_ATTR2_POP, (const char *)csr_data, csr_len) == 0); /* disable PoP */ st_disable_pop(); /* clear callback */ if (est_set_csr_cb(ectx, NULL)) { printf("\nUnable to set EST CSR Attributes callback. Aborting!!!\n"); exit(1); } /* Real base64 string PoP should not be added - should pass */ rc = est_server_init_csrattrs(ectx, TEST_ATTR_NOPOP, strlen(TEST_ATTR_NOPOP)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ATTR_NOPOP)); CU_ASSERT(strncmp(TEST_ATTR_NOPOP, (const char *)csr_data, csr_len) == 0); /* All ASN.1 types supported by OpenSSL */ rc = est_server_init_csrattrs(ectx, TEST_ALL_ATTR, strlen(TEST_ALL_ATTR)); CU_ASSERT(rc == EST_ERR_NONE); rc = est_client_get_csrattrs(ctx, &csr_data, &csr_len); CU_ASSERT(rc == EST_ERR_NONE); CU_ASSERT(csr_len == strlen(TEST_ALL_ATTR)); CU_ASSERT(strncmp(TEST_ALL_ATTR, (const char *)csr_data, csr_len) == 0); rc = est_server_init_csrattrs(ectx, TEST_1025_NOPOP, strlen(TEST_1025_NOPOP)); CU_ASSERT(rc != EST_ERR_NONE); rc = est_server_init_csrattrs(ectx, TEST_LONG_ATTR, strlen(TEST_LONG_ATTR)); CU_ASSERT(rc != EST_ERR_NONE); if (ctx) { est_destroy(ctx); } if (cacerts) { free(cacerts); } if (pkey) { free(pkey); } }
/* * This is the point of this entire file. * * It fills in an already allocated working key, based on the private key */ bool hss_generate_working_key( bool (*read_private_key)(unsigned char *private_key, size_t len_private_key, void *context), void *context, const unsigned char *aux_data, size_t len_aux_data, /* Optional */ struct hss_working_key *w, struct hss_extra_info *info) { struct hss_extra_info temp_info = { 0 }; if (!info) info = &temp_info; if (!w) { info->error_code = hss_error_got_null; return false; } w->status = hss_error_key_uninitialized; /* In case we detect an */ /* error midway */ if (!read_private_key && !context) { info->error_code = hss_error_no_private_buffer; return false; } /* Read the private key */ unsigned char private_key[ PRIVATE_KEY_LEN ]; if (read_private_key) { if (!read_private_key( private_key, PRIVATE_KEY_LEN, context)) { info->error_code = hss_error_private_key_read_failed; goto failed; } } else { memcpy( private_key, context, PRIVATE_KEY_LEN ); } /* * Make sure that the private key and the allocated working key are * compatible; that the working_key was initialized with the same * parameter set */ { if (w->levels > MAX_HSS_LEVELS) { info->error_code = hss_error_internal; goto failed; } unsigned char compressed[PRIVATE_KEY_PARAM_SET_LEN]; param_set_t lm_type[MAX_HSS_LEVELS], lm_ots_type[MAX_HSS_LEVELS]; int i; for (i=0; i<w->levels; i++) { lm_type[i] = w->tree[i]->lm_type; lm_ots_type[i] = w->tree[i]->lm_ots_type; } if (!hss_compress_param_set( compressed, w->levels, lm_type, lm_ots_type, sizeof compressed )) { /* We're passed an unsupported param set */ info->error_code = hss_error_internal; goto failed; } if (0 != memcmp( private_key + PRIVATE_KEY_PARAM_SET, compressed, PRIVATE_KEY_PARAM_SET_LEN )) { /* The working set was initiallized with a different parmset */ info->error_code = hss_error_incompatible_param_set; goto failed; } } sequence_t current_count = get_bigendian( private_key + PRIVATE_KEY_INDEX, PRIVATE_KEY_INDEX_LEN ); if (current_count > w->max_count) { info->error_code = hss_error_private_key_expired; /* Hey! We */ goto failed; /* can't generate any more signatures */ } hss_set_reserve_count(w, current_count); memcpy( w->private_key, private_key, PRIVATE_KEY_LEN ); /* Initialize all the levels of the tree */ /* Initialize the current count for each level (from the bottom-up) */ int i; sequence_t count = current_count; for (i = w->levels - 1; i >= 0 ; i--) { struct merkle_level *tree = w->tree[i]; unsigned index = count & tree->max_index; count >>= tree->level; tree->current_index = index; } /* Initialize the I values */ for (i = 0; i < w->levels; i++) { struct merkle_level *tree = w->tree[i]; /* Initialize the I, I_next elements */ if (i == 0) { /* The root seed, I value is derived from the secret key */ hss_generate_root_seed_I_value( tree->seed, tree->I, private_key+PRIVATE_KEY_SEED ); /* We don't use the I_next value */ } else { /* The seed, I is derived from the parent's values */ /* Where we are in the Merkle tree */ struct merkle_level *parent = w->tree[i-1]; merkle_index_t index = parent->current_index; hss_generate_child_seed_I_value( tree->seed, tree->I, parent->seed, parent->I, index, parent->lm_type, parent->lm_ots_type ); /* The next seed, I is derived from either the parent's I */ /* or the parent's next value */ if (index == tree->max_index) { hss_generate_child_seed_I_value( tree->seed_next, tree->I_next, parent->seed_next, parent->I_next, 0, parent->lm_type, parent->lm_ots_type); } else { hss_generate_child_seed_I_value( tree->seed_next, tree->I_next, parent->seed, parent->I, index+1, parent->lm_type, parent->lm_ots_type); } } } /* Generate the expanded aux data structure (or NULL if we don't have a */ /* viable aux structure */ struct expanded_aux_data *expanded_aux, temp_aux; expanded_aux = hss_expand_aux_data( aux_data, len_aux_data, &temp_aux, w->tree[0]->hash_size, w ); /* * Now, build all the subtrees within the tree * * We initialize the various data structures, and create a list of * the nodes on the bottom levels of the subtrees that need to be * initialized */ /* There are enough structures in this array to handle the maximum */ /* number of orders we'll ever see */ struct init_order order[MAX_HSS_LEVELS * MAX_SUBLEVELS * NUM_SUBTREE]; struct init_order *p_order = order; int count_order = 0; /* Step through the levels, and for each Merkle tree, compile a list of */ /* the orders to initialize the bottoms of the subtrees that we'll need */ for (i = w->levels - 1; i >= 0 ; i--) { struct merkle_level *tree = w->tree[i]; unsigned hash_size = tree->hash_size; /* The current count within this tree */ merkle_index_t tree_count = tree->current_index; /* The index of the leaf we're on */ merkle_index_t leaf_index = tree_count; /* Generate the active subtrees */ int j; int bot_level_subtree = tree->level; /* The level of the bottom of */ /* the subtree */ unsigned char *active_prev_node = 0; unsigned char *next_prev_node = 0; for (j=tree->sublevels-1; j>=0; j--) { /* The height of this subtree */ int h_subtree = (j == 0) ? tree->top_subtree_size : tree->subtree_size; /* Initialize the active tree */ struct subtree *active = tree->subtree[j][ACTIVE_TREE]; /* Total number of leaf nodes below this subtree */ merkle_index_t size_subtree = (merkle_index_t)1 << (h_subtree + active->levels_below); /* Fill in the leaf index that's on the left side of this subtree */ /* This is the index of the leaf that we did when we first */ /* entered the active subtree */ merkle_index_t left_leaf = leaf_index & ~(size_subtree - 1); /* This is the number of leaves we've done in this subtree */ merkle_index_t subtree_count = leaf_index - left_leaf; /* If we're not in the bottom tree, it's possible that the */ /* update process will miss the very first update before we */ /* need to sign. To account for that, generate one more */ /* node than what our current count would suggest */ if (i != w->levels - 1) { subtree_count++; } active->current_index = 0; active->left_leaf = left_leaf; merkle_index_t num_bottom_nodes = (merkle_index_t)1 << h_subtree; /* Check if we have aux data at this level */ int already_computed_lower = 0; if (i == 0) { merkle_index_t lower_index = num_bottom_nodes-1; merkle_index_t node_offset = active->left_leaf>>active->levels_below; if (hss_extract_aux_data(expanded_aux, active->level+h_subtree, w, &active->nodes[ hash_size * lower_index ], node_offset, num_bottom_nodes)) { /* We do have it precomputed in our aux data */ already_computed_lower = 1; } } /* No aux data at this level; schedule the bottom row to be computed */ /* Schedule the creation of the entire active tree */ p_order->tree = tree; p_order->subtree = active; p_order->count_nodes = (merkle_index_t)1 << h_subtree; /* All */ /* the nodes in this subtree */ p_order->next_tree = 0; /* Mark the root we inherented from the subtree just below us */ p_order->prev_node = already_computed_lower ? NULL : active_prev_node; p_order->prev_index = (tree->current_index >> active->levels_below) & (num_bottom_nodes-1); p_order->already_computed_lower = already_computed_lower; p_order++; count_order++; /* For the next subtree, here's where our root will be */ active_prev_node = &active->nodes[0]; /* And initialize the building tree, assuming there is one, and */ /* assuming that the active subtree isn't at the right edge of */ /* the Merkle tree */ if (j > 0 && (leaf_index + size_subtree <= tree->max_index )) { struct subtree *building = tree->subtree[j][BUILDING_TREE]; /* The number of leaves that make up one bottom node */ /* of this subtree */ merkle_index_t size_below_tree = (merkle_index_t)1 << building->levels_below; /* We need to initialize the building tree current index */ /* to a value at least as large as subtree_count */ /* We'd prefer not to have to specificallly initialize */ /* the stack, and so we round up to the next place the */ /* stack is empty */ merkle_index_t building_count = (subtree_count + size_below_tree - 1) & ~(size_below_tree - 1); /* # of bottom level nodes we've building right now */ merkle_index_t num_nodes = building_count >> building->levels_below; building->left_leaf = left_leaf + size_subtree; building->current_index = building_count; /* Check if this is already in the aux data */ already_computed_lower = 0; if (i == 0) { merkle_index_t lower_index = num_bottom_nodes-1; merkle_index_t node_offset = building->left_leaf>>building->levels_below; if (hss_extract_aux_data(expanded_aux, building->level+h_subtree, w, &building->nodes[ hash_size * lower_index ], node_offset, num_nodes)) { /* We do have it precomputed in our aux data */ already_computed_lower = 1; } } /* Schedule the creation of the subset of the building tree */ p_order->tree = tree; p_order->subtree = building; /* # of nodes to construct */ p_order->count_nodes = num_nodes; p_order->next_tree = 0; /* We generally can't use the prev_node optimization */ p_order->prev_node = NULL; p_order->prev_index = 0; p_order->already_computed_lower = already_computed_lower; p_order++; count_order++; } else if (j > 0) {
/** * Initialize crypto library, generate keys */ void key_init(void) { #ifndef NO_ENCRYPTION char *keyname; int size, i; uint8_t curve; crypto_init(sys_keys); if ((keyfile_count == 0) && (keyinfo_count == 0)) { privkey[0].rsa = gen_RSA_key(0, RSA_EXP, NULL); if (!privkey[0].key) { exit(ERR_CRYPTO); } privkey_type[0] = KEYBLOB_RSA; key_count = 1; } else if (keyinfo_count != 0) { key_count = 0; for (i = 0; i < keyinfo_count; i++) { if (keyfile_count <= i) { keyname = NULL; } else { keyname = keyfile[i]; } if (!strncmp(keyinfo[i], "ec:", 3)) { curve = get_curve(&keyinfo[i][3]); if (curve == 0) { log0(0, 0, 0, "Invalid EC curve: %s", &keyinfo[i][3]); exit(ERR_PARAM); } privkey[key_count].ec = gen_EC_key(curve, 0, keyname); privkey_type[key_count] = KEYBLOB_EC; if (!privkey[key_count].key) { exit(ERR_CRYPTO); } } else if (!strncmp(keyinfo[i], "rsa:", 4)) { size = atoi(&keyinfo[i][4]); if ((size < 512) || (size > 2048)) { log0(0, 0, 0, "Invalid RSA key size: %s", &keyinfo[i][4]); exit(ERR_PARAM); } privkey[key_count].rsa = gen_RSA_key(size, RSA_EXP, keyname); privkey_type[key_count] = KEYBLOB_RSA; if (!privkey[key_count].key) { exit(ERR_CRYPTO); } } else { log0(0, 0, 0, "Invalid keyinfo entry: %s", keyinfo[i]); exit(ERR_PARAM); } key_count++; } } else { for (i = 0; i < keyfile_count; i++) { privkey[key_count] = read_private_key(keyfile[i], &privkey_type[key_count]); if (privkey_type[key_count] == 0) { exit(ERR_CRYPTO); } key_count++; } } #endif }