END_TEST START_TEST(test_newhope_ke_fail_i) { diffie_hellman_t *i_nh; char buf_ff[2048]; int i; chunk_t i_msg; chunk_t r_msg[] = { chunk_empty, chunk_from_chars(0x00), chunk_create(buf_ff, 2047), chunk_create(buf_ff, 2048), }; memset(buf_ff, 0xff, sizeof(buf_ff)); for (i = 0; i < countof(r_msg); i++) { i_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT); ck_assert(i_nh != NULL); ck_assert(i_nh->get_my_public_value(i_nh, &i_msg)); ck_assert(!i_nh->set_other_public_value(i_nh, r_msg[i])); chunk_free(&i_msg); i_nh->destroy(i_nh); } }
END_TEST START_TEST(test_newhope_ke_fail_r) { diffie_hellman_t *r_nh; char buf_ff[1824]; int i; chunk_t i_msg[] = { chunk_empty, chunk_from_chars(0x00), chunk_create(buf_ff, 1823), chunk_create(buf_ff, 1824), }; memset(buf_ff, 0xff, sizeof(buf_ff)); for (i = 0; i < countof(i_msg); i++) { r_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT); ck_assert(r_nh != NULL); ck_assert(!r_nh->set_other_public_value(r_nh, i_msg[i])); r_nh->destroy(r_nh); } }
END_TEST /******************************************************************************* * BASE64 encoding test */ START_TEST(test_base64) { /* test vectors from RFC 4648: * * BASE64("") = "" * BASE64("f") = "Zg==" * BASE64("fo") = "Zm8=" * BASE64("foo") = "Zm9v" * BASE64("foob") = "Zm9vYg==" * BASE64("fooba") = "Zm9vYmE=" * BASE64("foobar") = "Zm9vYmFy" */ typedef struct { char *in; char *out; } testdata_t; testdata_t test[] = { {"", ""}, {"f", "Zg=="}, {"fo", "Zm8="}, {"foo", "Zm9v"}, {"foob", "Zm9vYg=="}, {"fooba", "Zm9vYmE="}, {"foobar", "Zm9vYmFy"}, }; int i; for (i = 0; i < countof(test); i++) { chunk_t out; out = chunk_to_base64(chunk_create(test[i].in, strlen(test[i].in)), NULL); ck_assert_str_eq(out.ptr, test[i].out); free(out.ptr); } for (i = 0; i < countof(test); i++) { chunk_t out; out = chunk_from_base64(chunk_create(test[i].out, strlen(test[i].out)), NULL); fail_unless(strneq(out.ptr, test[i].in, out.len), "base64 conversion error - should '%s', is %#B", test[i].in, &out); free(out.ptr); } }
/** * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3 */ static TNC_Result tnc_imc_receivemessage(TNC_IMCID imc_id, TNC_ConnectionID connection_id, TNC_BufferReference msg, TNC_UInt32 msg_len, TNC_MessageType msg_type) { imc_state_t *state; imc_msg_t *in_msg; TNC_Result result; if (!imc_android) { DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); return TNC_RESULT_NOT_INITIALIZED; } if (!imc_android->get_state(imc_android, connection_id, &state)) { return TNC_RESULT_FATAL; } in_msg = imc_msg_create_from_data(imc_android, state, connection_id, msg_type, chunk_create(msg, msg_len)); result = receive_message((imc_android_state_t*)state, in_msg); in_msg->destroy(in_msg); return result; }
void *chunk_find(size_t size) { unsigned int i; t_mem m; t_chunk c; m.size = size; i = -1; while (++i < g_malloc_memory->size) { c = *(t_chunk *)array_get(g_malloc_memory, i); if ((size <= SMALL_SIZE && c.size != SMALL_CHUNK) || (size > SMALL_SIZE && size <= MEDIUM_SIZE && c.size != MEDIUM_CHUNK) || (size > MEDIUM_SIZE && c.size >= MEDIUM_CHUNK)) continue ; m.start = mem_find(&c, size); if (m.start) { array_add(c.mem, &m); return (m.start); } } c = *chunk_create(size); m.start = c.start; array_add(c.mem, &m); return (m.start); }
/** * load the credential from a file descriptor */ static void *load_from_fd(int fd, credential_type_t type, int subtype, identification_t *subject, x509_flag_t flags) { char buf[8096]; char *pos = buf; ssize_t len, total = 0; while (TRUE) { len = read(fd, pos, buf + sizeof(buf) - pos); if (len < 0) { DBG1(DBG_LIB, "reading from file descriptor failed: %s", strerror(errno)); return NULL; } if (len == 0) { break; } total += len; if (total == sizeof(buf)) { DBG1(DBG_LIB, "buffer too small to read from file descriptor"); return NULL; } } return load_from_blob(chunk_create(buf, total), type, subtype, subject, flags); }
/** * see section 3.8.4 of TCG TNC IF-IMV Specification 1.3 */ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, TNC_ConnectionID connection_id, TNC_BufferReference msg, TNC_UInt32 msg_len, TNC_MessageType msg_type) { imv_state_t *state; imv_msg_t *in_msg; TNC_Result result; if (!imv_os) { DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); return TNC_RESULT_NOT_INITIALIZED; } if (!imv_os->get_state(imv_os, connection_id, &state)) { return TNC_RESULT_FATAL; } in_msg = imv_msg_create_from_data(imv_os, state, connection_id, msg_type, chunk_create(msg, msg_len)); result = receive_message(state, in_msg); in_msg->destroy(in_msg); return result; }
/** * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3 */ TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id, TNC_ConnectionID connection_id, TNC_UInt32 msg_flags, TNC_BufferReference msg, TNC_UInt32 msg_len, TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype, TNC_UInt32 src_imv_id, TNC_UInt32 dst_imc_id) { imc_state_t *state; imc_msg_t *in_msg; TNC_Result result; if (!imc_os) { DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); return TNC_RESULT_NOT_INITIALIZED; } if (!imc_os->get_state(imc_os, connection_id, &state)) { return TNC_RESULT_FATAL; } in_msg = imc_msg_create_from_long_data(imc_os, state, connection_id, src_imv_id, dst_imc_id,msg_vid, msg_subtype, chunk_create(msg, msg_len)); result =receive_message(in_msg); in_msg->destroy(in_msg); return result; }
/** * Read input data as chunk */ static chunk_t read_from_stream(FILE *stream) { char buf[8096]; size_t len, total = 0; while (TRUE) { len = fread(buf + total, 1, sizeof(buf) - total, stream); if (len < (sizeof(buf) - total)) { if (ferror(stream)) { return chunk_empty; } if (feof(stream)) { return chunk_clone(chunk_create(buf, total + len)); } } total += len; if (total == sizeof(buf)) { fprintf(stderr, "buffer too small to read input!\n"); return chunk_empty; } } }
static int allocator_alloc(allocator_t* allocator, int size) { chunk_t* chunk_free; chunk_t* chunk_cur; chunk_t* chunk_split; int free_page_num; int page_num; int left_page_num; int heap_offset; if(size == 0) return -1; size = size + (AV_PAGE_SIZE - 1); page_num = size / AV_PAGE_SIZE; chunk_free = NULL; chunk_cur = chunk_list_head(allocator->list); while(chunk_cur != NULL) { //* search the list to find a best chunk. if(chunk_cur->is_free && chunk_cur->page_num >= page_num) { if(chunk_free == NULL || chunk_cur->page_num < chunk_free->page_num) chunk_free = chunk_cur; if(chunk_cur->page_num == page_num) break; } chunk_cur = chunk_cur->next; } if(chunk_free != NULL) { free_page_num = chunk_free->page_num; chunk_free->is_free = 0; chunk_free->page_num = page_num; if(free_page_num > page_num) { left_page_num = free_page_num - page_num; chunk_split = chunk_create(chunk_free->page_offset + page_num, left_page_num); chunk_list_insert_after(allocator->list, chunk_free, chunk_split); } } if(chunk_free != NULL) heap_offset = chunk_free->page_offset * AV_PAGE_SIZE; else heap_offset = -1; return heap_offset; }
END_TEST /******************************************************************************* * chunk_create_cat */ START_TEST(test_chunk_create_cat) { chunk_t foo, bar; chunk_t a, b, c; u_char *ptra, *ptrb; foo = chunk_from_str("foo"); bar = chunk_from_str("bar"); /* to simplify things we use the chunk_cata macro */ a = chunk_empty; b = chunk_empty; c = chunk_cata("cc", a, b); ck_assert_int_eq(c.len, 0); ck_assert(c.ptr != NULL); a = foo; b = bar; c = chunk_cata("cc", a, b); ck_assert_int_eq(c.len, 6); ck_assert(chunk_equals(c, chunk_from_str("foobar"))); a = chunk_clone(foo); b = chunk_clone(bar); c = chunk_cata("mm", a, b); ck_assert_int_eq(c.len, 6); ck_assert(chunk_equals(c, chunk_from_str("foobar"))); a = chunk_clone(foo); b = chunk_clone(bar); ptra = a.ptr; ptrb = b.ptr; c = chunk_cata("ss", a, b); ck_assert_int_eq(c.len, 6); ck_assert(chunk_equals(c, chunk_from_str("foobar"))); /* check memory area of cleared chunk */ ck_assert(!chunk_equals(foo, chunk_create(ptra, 3))); ck_assert(!chunk_equals(bar, chunk_create(ptrb, 3))); }
/** * Described in header. */ bool chunk_from_fd(int fd, chunk_t *out) { struct stat sb; char *buf, *tmp; ssize_t len, total = 0, bufsize; if (fstat(fd, &sb) == 0 && S_ISREG(sb.st_mode)) { bufsize = sb.st_size; } else { bufsize = 256; } buf = malloc(bufsize); if (!buf) { /* for huge files */ return FALSE; } while (TRUE) { len = read(fd, buf + total, bufsize - total); if (len < 0) { free(buf); return FALSE; } if (len == 0) { break; } total += len; if (total == bufsize) { bufsize *= 2; tmp = realloc(buf, bufsize); if (!tmp) { free(buf); return FALSE; } buf = tmp; } } if (total == 0) { free(buf); buf = NULL; } else if (total < bufsize) { buf = realloc(buf, total); } *out = chunk_create(buf, total); return TRUE; }
/** * Get a measurement for the given attribute type from the Android IMC. * NULL is returned if no measurement is available or an error occurred. * * The optional args is an enumerator over char* (gets destroyed). */ static pa_tnc_attr_t *get_measurement(pen_type_t attr_type, enumerator_t *args) { JNIEnv *env; pa_tnc_attr_t *attr; jmethodID method_id; jbyteArray jmeasurement; jobjectArray jargs = NULL; chunk_t data; androidjni_attach_thread(&env); if (args) { jargs = string_array_create(env, args); if (!jargs) { goto failed; } method_id = (*env)->GetMethodID(env, android_imc_cls, "getMeasurement", "(II[Ljava/lang/String;)[B"); } else { method_id = (*env)->GetMethodID(env, android_imc_cls, "getMeasurement", "(II)[B"); } if (!method_id) { goto failed; } jmeasurement = (*env)->CallObjectMethod(env, android_imc, method_id, attr_type.vendor_id, attr_type.type, jargs); if (!jmeasurement || androidjni_exception_occurred(env)) { goto failed; } data = chunk_create((*env)->GetByteArrayElements(env, jmeasurement, NULL), (*env)->GetArrayLength(env, jmeasurement)); if (!data.ptr) { goto failed; } attr = imcv_pa_tnc_attributes->construct(imcv_pa_tnc_attributes, attr_type.vendor_id, attr_type.type, data); (*env)->ReleaseByteArrayElements(env, jmeasurement, data.ptr, JNI_ABORT); androidjni_detach_thread(); return attr; failed: androidjni_exception_occurred(env); androidjni_detach_thread(); return NULL; }
/** * read the last serial number from file */ static chunk_t read_serial(void) { chunk_t hex, serial = chunk_empty; char one[] = {0x01}; FILE *fd; fd = fopen(OPENAC_SERIAL, "r"); if (fd) { hex = chunk_alloca(64); hex.len = fread(hex.ptr, 1, hex.len, fd); if (hex.len) { /* remove any terminating newline character */ if (hex.ptr[hex.len-1] == '\n') { hex.len--; } serial = chunk_alloca((hex.len / 2) + (hex.len % 2)); serial = chunk_from_hex(hex, serial.ptr); } fclose(fd); } else { DBG1(DBG_LIB, " file '%s' does not exist yet - serial number " "set to 01", OPENAC_SERIAL); } if (!serial.len) { return chunk_clone(chunk_create(one, 1)); } if (chunk_increment(serial)) { /* overflow, prepend 0x01 */ return chunk_cat("cc", chunk_create(one, 1), serial); } return chunk_clone(serial); }
/** * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3 */ TNC_Result TNC_IMV_ReceiveMessageLong(TNC_IMVID imv_id, TNC_ConnectionID connection_id, TNC_UInt32 msg_flags, TNC_BufferReference msg, TNC_UInt32 msg_len, TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype, TNC_UInt32 src_imc_id, TNC_UInt32 dst_imv_id) { return receive_message(imv_id, connection_id, msg_flags, chunk_create(msg, msg_len), msg_vid, msg_subtype, src_imc_id, dst_imv_id); }
/* Generate a cookie. * First argument is true if we're to create an Initiator cookie. * Length SHOULD be a multiple of sizeof(u_int32_t). */ void get_cookie(bool initiator, u_int8_t *cookie, int length, ip_address *addr) { hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); u_char buffer[HASH_SIZE_SHA1]; do { if (initiator) { rng_t *rng; rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); rng->get_bytes(rng, length, cookie); rng->destroy(rng); } else /* Responder cookie */ { chunk_t addr_chunk, secret_chunk, counter_chunk; size_t addr_len; static u_int32_t counter = 0; unsigned char addr_buf[ sizeof(union {struct in_addr A; struct in6_addr B;})]; addr_len = addrbytesof(addr, addr_buf, sizeof(addr_buf)); addr_chunk = chunk_create(addr_buf, addr_len); secret_chunk = chunk_create(secret_of_the_day, HASH_SIZE_SHA1); counter++; counter_chunk = chunk_create((void *) &counter, sizeof(counter)); hasher->get_hash(hasher, addr_chunk, NULL); hasher->get_hash(hasher, secret_chunk, NULL); hasher->get_hash(hasher, counter_chunk, buffer); memcpy(cookie, buffer, length); } } while (is_zero_cookie(cookie)); /* probably never loops */ hasher->destroy(hasher); }
/** * see section 3.8.4 of TCG TNC IF-IMV Specification 1.3 */ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, TNC_ConnectionID connection_id, TNC_BufferReference msg, TNC_UInt32 msg_len, TNC_MessageType msg_type) { TNC_VendorID msg_vid; TNC_MessageSubtype msg_subtype; msg_vid = msg_type >> 8; msg_subtype = msg_type & TNC_SUBTYPE_ANY; return receive_message(imv_id, connection_id, 0, chunk_create(msg, msg_len), msg_vid, msg_subtype, 0, TNC_IMVID_ANY); }
int main(int argc, char* argv[]) { int err, i; char key[10], value[10]; CHUNK* chunk; /* create database file */ err = chunk_create(FILENAME, HTABLE_SIZE); if (err) { printf("Error: cant create chunk file\n"); return -1; } /* open database file */ chunk = malloc(sizeof(CHUNK)); err = chunk_open(chunk, FILENAME, CACHE_SIZE); if (err) { free(chunk); printf("Error: problem with open chunk file\n"); return -2; } /* insert */ for(i=0; i<SIZE; i++) { sprintf(key, "%s%d", "key", i); sprintf(value, "%s%d", "value", i); chunk_set(chunk, key, value); } /* remove */ printf("chunk_remove key5 %d\n", chunk_remove(chunk, "key5")); printf("chunk_remove key7 %d\n", chunk_remove(chunk, "key7")); /* get */ for(i=0; i<SIZE; i++) { sprintf(key, "%s%d", "key", i); printf("chunk_get %s = %s\n",key, chunk_get(chunk, key)); } /* forEach */ chunk_for_each(chunk, display); /* close */ chunk_close(chunk); free(chunk); return 0; }
/** * Get a TCP or UDP port list from strongswan.conf */ static linked_list_t* get_port_list(char *label) { char key[40], *value; linked_list_t *list; chunk_t port_list, port_item, port_start; port_range_t *port_range; list = linked_list_create(); snprintf(key, sizeof(key), "libimcv.plugins.imv-scanner.%s_ports", label); value = lib->settings->get_str(lib->settings, key, NULL); if (!value) { DBG1(DBG_IMV, "%s not defined", key); return list; } port_list = chunk_create(value, strlen(value)); DBG2(DBG_IMV, "list of %s ports that %s:", label, closed_port_policy ? "are allowed to be open" : "must be closed"); while (eat_whitespace(&port_list)) { if (!extract_token(&port_item, ' ', &port_list)) { /* reached last port item */ port_item = port_list; port_list = chunk_empty; } port_range = malloc_thing(port_range_t); port_range->start = atoi(port_item.ptr); if (extract_token(&port_start, '-', &port_item) && port_item.len) { port_range->stop = atoi(port_item.ptr); } else { port_range->stop = port_range->start; } DBG2(DBG_IMV, "%5u - %5u", port_range->start, port_range->stop); list->insert_last(list, port_range); } return list; }
/** * Read a chunk of data from TLS, returning a reader for it */ static bio_reader_t* read_tls(tls_socket_t *tls, size_t len) { ssize_t got, total = 0; char *buf; buf = malloc(len); while (total < len) { got = tls->read(tls, buf + total, len - total, TRUE); if (got <= 0) { free(buf); return NULL; } total += got; } return bio_reader_create_own(chunk_create(buf, len)); }
/* * Defined in header. */ chunk_t asn1_oid_from_string(char *str) { enumerator_t *enumerator; u_char buf[64]; char *end; int i = 0, pos = 0, shift; u_int val, shifted_val, first = 0; enumerator = enumerator_create_token(str, ".", ""); while (enumerator->enumerate(enumerator, &str)) { val = strtoul(str, &end, 10); if (end == str || pos > countof(buf)) { pos = 0; break; } switch (i++) { case 0: first = val; break; case 1: buf[pos++] = first * 40 + val; break; default: shift = 28; /* sufficient to handle 32 bit node numbers */ while (shift) { shifted_val = val >> shift; shift -= 7; if (shifted_val) /* do not encode leading zeroes */ { buf[pos++] = 0x80 | (shifted_val & 0x7F); } } buf[pos++] = val & 0x7F; } } enumerator->destroy(enumerator); return chunk_clone(chunk_create(buf, pos)); }
END_TEST /******************************************************************************* * BASE32 encoding test */ START_TEST(test_base32) { /* test vectors from RFC 4648: * * BASE32("") = "" * BASE32("f") = "MY======" * BASE32("fo") = "MZXQ====" * BASE32("foo") = "MZXW6===" * BASE32("foob") = "MZXW6YQ=" * BASE32("fooba") = "MZXW6YTB" * BASE32("foobar") = "MZXW6YTBOI======" */ typedef struct { char *in; char *out; } testdata_t; testdata_t test[] = { {"", ""}, {"f", "MY======"}, {"fo", "MZXQ===="}, {"foo", "MZXW6==="}, {"foob", "MZXW6YQ="}, {"fooba", "MZXW6YTB"}, {"foobar", "MZXW6YTBOI======"}, }; int i; for (i = 0; i < countof(test); i++) { chunk_t out; out = chunk_to_base32(chunk_create(test[i].in, strlen(test[i].in)), NULL); ck_assert_str_eq(out.ptr, test[i].out); free(out.ptr); } }
/** * Described in header. */ chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...) { va_list chunks; chunk_t construct = chunk_create(ptr, 0); va_start(chunks, mode); while (TRUE) { bool free_chunk = FALSE, clear_chunk = FALSE; chunk_t ch; switch (*mode++) { case 's': clear_chunk = TRUE; /* FALL */ case 'm': free_chunk = TRUE; /* FALL */ case 'c': ch = va_arg(chunks, chunk_t); memcpy(ptr, ch.ptr, ch.len); ptr += ch.len; construct.len += ch.len; if (clear_chunk) { chunk_clear(&ch); } else if (free_chunk) { free(ch.ptr); } continue; default: break; } break; } va_end(chunks); return construct; }
/** * load the credential from a file */ static void *load_from_file(char *file, credential_type_t type, int subtype, chunk_t(*cb)(void*,int), void *cb_data, x509_flag_t flags) { void *cred = NULL; struct stat sb; void *addr; int fd; fd = open(file, O_RDONLY); if (fd == -1) { DBG1(DBG_LIB, " opening '%s' failed: %s", file, strerror(errno)); return NULL; } if (fstat(fd, &sb) == -1) { DBG1(DBG_LIB, " getting file size of '%s' failed: %s", file, strerror(errno)); close(fd); return NULL; } addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { DBG1(DBG_LIB, " mapping '%s' failed: %s", file, strerror(errno)); close(fd); return NULL; } cred = load_from_blob(chunk_create(addr, sb.st_size), type, subtype, cb, cb_data, flags); munmap(addr, sb.st_size); close(fd); return cred; }
static allocator_t* allocator_create(int heap_size) { allocator_t* allocator; chunk_t* chunk; allocator = (allocator_t*)malloc(sizeof(allocator_t)); if(allocator == NULL) return NULL; allocator->list = chunk_list_create(); if(allocator->list == NULL) { loge("can not create chunk list for allocator, return fail."); free(allocator); return NULL; } allocator->heap_size = heap_size; chunk = chunk_create(0, heap_size/AV_PAGE_SIZE); if(chunk == NULL) { loge("can not create a chunk when creating allocator, return fail."); chunk_list_destroy(allocator->list); free(allocator); return NULL; } chunk_list_insert_head(allocator->list, chunk); return allocator; }
int main(int argc, char *argv[]) { const proposal_token_t *token; aead_t *aead; crypter_t *crypter; char buffer[1024], assoc[8], iv[32]; size_t bs; int i = 0, limit = 0; library_init(NULL, "crypt_burn"); lib->plugins->load(lib->plugins, PLUGINS); atexit(library_deinit); printf("loaded: %s\n", PLUGINS); memset(buffer, 0x12, sizeof(buffer)); memset(assoc, 0x34, sizeof(assoc)); memset(iv, 0x56, sizeof(iv)); if (argc < 2) { fprintf(stderr, "usage: %s <algorithm>!\n", argv[0]); return 1; } if (argc > 2) { limit = atoi(argv[2]); } token = lib->proposal->get_token(lib->proposal, argv[1]); if (!token) { fprintf(stderr, "algorithm '%s' unknown!\n", argv[1]); return 1; } if (token->type != ENCRYPTION_ALGORITHM) { fprintf(stderr, "'%s' is not an encryption/aead algorithm!\n", argv[1]); return 1; } if (encryption_algorithm_is_aead(token->algorithm)) { aead = lib->crypto->create_aead(lib->crypto, token->algorithm, token->keysize / 8, 0); if (!aead) { fprintf(stderr, "aead '%s' not supported!\n", argv[1]); return 1; } while (TRUE) { if (!aead->encrypt(aead, chunk_create(buffer, sizeof(buffer) - aead->get_icv_size(aead)), chunk_from_thing(assoc), chunk_create(iv, aead->get_iv_size(aead)), NULL)) { fprintf(stderr, "aead encryption failed!\n"); return 1; } if (!aead->decrypt(aead, chunk_create(buffer, sizeof(buffer)), chunk_from_thing(assoc), chunk_create(iv, aead->get_iv_size(aead)), NULL)) { fprintf(stderr, "aead integrity check failed!\n"); return 1; } if (limit && ++i == limit) { break; } } aead->destroy(aead); } else { crypter = lib->crypto->create_crypter(lib->crypto, token->algorithm, token->keysize / 8); if (!crypter) { fprintf(stderr, "crypter '%s' not supported!\n", argv[1]); return 1; } bs = crypter->get_block_size(crypter); while (TRUE) { if (!crypter->encrypt(crypter, chunk_create(buffer, sizeof(buffer) / bs * bs), chunk_create(iv, crypter->get_iv_size(crypter)), NULL)) { continue; } if (!crypter->decrypt(crypter, chunk_create(buffer, sizeof(buffer) / bs * bs), chunk_create(iv, crypter->get_iv_size(crypter)), NULL)) { continue; } if (limit && ++i == limit) { break; } } crypter->destroy(crypter); } return 0; }
/** * Determine the type of the attribute and its value */ static bool parse_attributes(char *name, char *value, value_type_t *value_type, configuration_attribute_type_t *type, configuration_attribute_type_t *type_ip6, chunk_t *blob) { host_t *addr = NULL, *mask = NULL; chunk_t addr_chunk, mask_chunk, blob_next; char *text = "", *pos_addr, *pos_mask, *pos_next, *endptr; int i; switch (*value_type) { case VALUE_STRING: *blob = chunk_create(value, strlen(value)); *blob = chunk_clone(*blob); break; case VALUE_HEX: *blob = chunk_from_hex(chunk_create(value, strlen(value)), NULL); break; case VALUE_ADDR: addr = host_create_from_string(value, 0); if (addr == NULL) { fprintf(stderr, "invalid IP address: '%s'.\n", value); return FALSE; } addr_chunk = addr->get_address(addr); *blob = chunk_clone(addr_chunk); break; case VALUE_SUBNET: *blob = chunk_empty; pos_next = value; do { pos_addr = pos_next; pos_next = strchr(pos_next, ','); if (pos_next) { *pos_next = '\0'; pos_next += 1; } pos_mask = strchr(pos_addr, '/'); if (pos_mask == NULL) { fprintf(stderr, "invalid IPv4 subnet: '%s'.\n", pos_addr); free(blob->ptr); return FALSE; } *pos_mask = '\0'; pos_mask += 1; addr = host_create_from_string(pos_addr, 0); mask = host_create_from_string(pos_mask, 0); if (addr == NULL || addr->get_family(addr) != AF_INET || mask == NULL || mask->get_family(addr) != AF_INET) { fprintf(stderr, "invalid IPv4 subnet: '%s/%s'.\n", pos_addr, pos_mask); DESTROY_IF(addr); DESTROY_IF(mask); free(blob->ptr); return FALSE; } addr_chunk = addr->get_address(addr); mask_chunk = mask->get_address(mask); blob_next = chunk_alloc(blob->len + UNITY_NETWORK_LEN); memcpy(blob_next.ptr, blob->ptr, blob->len); pos_addr = blob_next.ptr + blob->len; memset(pos_addr, 0x00, UNITY_NETWORK_LEN); memcpy(pos_addr, addr_chunk.ptr, 4); memcpy(pos_addr + 4, mask_chunk.ptr, 4); addr->destroy(addr); addr = NULL; mask->destroy(mask); chunk_free(blob); *blob = blob_next; } while (pos_next); break; case VALUE_NONE: *blob = chunk_empty; break; } /* init the attribute type */ *type = 0; *type_ip6 = 0; for (i = 0; i < countof(attr_info); i++) { if (strcaseeq(name, attr_info[i].keyword)) { *type = attr_info[i].type; *type_ip6 = attr_info[i].type_ip6; if (*value_type == VALUE_NONE) { *value_type = attr_info[i].value_type; return TRUE; } if (*value_type != attr_info[i].value_type && *value_type != VALUE_HEX) { switch (attr_info[i].value_type) { case VALUE_STRING: text = "a string"; break; case VALUE_HEX: text = "a hex"; break; case VALUE_ADDR: text = "an IP address"; break; case VALUE_SUBNET: text = "a subnet"; break; case VALUE_NONE: text = "no"; break; } fprintf(stderr, "the %s attribute requires %s value.\n", name, text); DESTROY_IF(addr); free(blob->ptr); return FALSE; } if (*value_type == VALUE_ADDR) { *type = (addr->get_family(addr) == AF_INET) ? attr_info[i].type : attr_info[i].type_ip6; addr->destroy(addr); } else if (*value_type == VALUE_HEX) { *value_type = attr_info[i].value_type; if (*value_type == VALUE_ADDR) { if (blob->len == 16) { *type = attr_info[i].type_ip6; } else if (blob->len != 4) { fprintf(stderr, "the %s attribute requires " "a valid IP address.\n", name); free(blob->ptr); return FALSE; } } } return TRUE; } } /* clean up */ DESTROY_IF(addr); /* is the attribute type numeric? */ *type = strtol(name, &endptr, 10); if (*endptr != '\0') { fprintf(stderr, "the %s attribute is not recognized.\n", name); free(blob->ptr); return FALSE; } if (*type < 1 || *type > 32767) { fprintf(stderr, "the attribute type must lie in the range 1..32767.\n"); free(blob->ptr); return FALSE; } if (*value_type == VALUE_NONE) { *value_type = VALUE_HEX; } return TRUE; }
/** * ipsec pool --statusattr - show all attribute entries */ void status_attr(bool hexout) { configuration_attribute_type_t type; value_type_t value_type; chunk_t value, addr_chunk, mask_chunk, identity_chunk; identification_t *identity; enumerator_t *enumerator; host_t *addr, *mask; char type_name[30]; bool first = TRUE; int i, identity_type; char *pool_name; /* enumerate over all attributes */ enumerator = db->query(db, "SELECT attributes.type, attribute_pools.name, " "identities.type, identities.data, attributes.value " "FROM attributes " "LEFT OUTER JOIN identities " "ON attributes.identity = identities.id " "LEFT OUTER JOIN attribute_pools " "ON attributes.pool = attribute_pools.id " "ORDER BY attributes.type, attribute_pools.name, " "identities.type, identities.data, attributes.value", DB_INT, DB_TEXT, DB_INT, DB_BLOB, DB_BLOB); if (enumerator) { while (enumerator->enumerate(enumerator, &type,&pool_name, &identity_type, &identity_chunk, &value)) { if (first) { printf(" type description pool " " identity value\n"); first = FALSE; } snprintf(type_name, sizeof(type_name), "%N", configuration_attribute_type_names, type); if (type_name[0] == '(') { type_name[0] = '\0'; } printf("%5d %-20s ",type, type_name); printf(" %-10s ", (pool_name ? pool_name : "")); if (identity_type) { identity = identification_create_from_encoding(identity_type, identity_chunk); printf(" %-20.20Y ", identity); identity->destroy(identity); } else { printf(" "); } value_type = VALUE_HEX; if (!hexout) { for (i = 0; i < countof(attr_info); i++) { if (type == attr_info[i].type) { value_type = attr_info[i].value_type; break; } } } switch (value_type) { case VALUE_ADDR: addr = host_create_from_chunk(AF_UNSPEC, value, 0); if (addr) { printf(" %H\n", addr); addr->destroy(addr); } else { /* value cannot be represented as an IP address */ printf(" %#B\n", &value); } break; case VALUE_SUBNET: if (value.len % UNITY_NETWORK_LEN == 0) { for (i = 0; i < value.len / UNITY_NETWORK_LEN; i++) { addr_chunk = chunk_create(value.ptr + i*UNITY_NETWORK_LEN, 4); addr = host_create_from_chunk(AF_INET, addr_chunk, 0); mask_chunk = chunk_create(addr_chunk.ptr + 4, 4); mask = host_create_from_chunk(AF_INET, mask_chunk, 0); printf("%s%H/%H", (i > 0) ? "," : " ", addr, mask); addr->destroy(addr); mask->destroy(mask); } printf("\n"); } else { /* value cannot be represented as a list of subnets */ printf(" %#B\n", &value); } break; case VALUE_STRING: printf("\"%.*s\"\n", (int)value.len, value.ptr); break; case VALUE_HEX: default: printf(" %#B\n", &value); } } enumerator->destroy(enumerator); } }
/** * Create a self-signed PKCS#10 certificate requesst. */ static int req() { cred_encoding_type_t form = CERT_ASN1_DER; key_type_t type = KEY_ANY; hash_algorithm_t digest = HASH_UNKNOWN; signature_params_t *scheme = NULL; certificate_t *cert = NULL; private_key_t *private = NULL; char *file = NULL, *keyid = NULL, *dn = NULL, *error = NULL; identification_t *id = NULL; linked_list_t *san; chunk_t encoding = chunk_empty; chunk_t challenge_password = chunk_empty; char *arg; bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE, lib->ns); san = linked_list_create(); while (TRUE) { switch (command_getopt(&arg)) { case 'h': goto usage; case 't': if (streq(arg, "rsa")) { type = KEY_RSA; } else if (streq(arg, "ecdsa")) { type = KEY_ECDSA; } else if (streq(arg, "bliss")) { type = KEY_BLISS; } else if (streq(arg, "priv")) { type = KEY_ANY; } else { error = "invalid input type"; goto usage; } continue; case 'g': if (!enum_from_name(hash_algorithm_short_names, arg, &digest)) { error = "invalid --digest type"; goto usage; } continue; case 'R': if (streq(arg, "pss")) { pss = TRUE; } else if (!streq(arg, "pkcs1")) { error = "invalid RSA padding"; goto usage; } continue; case 'i': file = arg; continue; case 'd': dn = arg; continue; case 'a': san->insert_last(san, identification_create_from_string(arg)); continue; case 'p': challenge_password = chunk_create(arg, strlen(arg)); continue; case 'f': if (!get_form(arg, &form, CRED_CERTIFICATE)) { error = "invalid output format"; goto usage; } continue; case 'x': keyid = arg; continue; case EOF: break; default: error = "invalid --req option"; goto usage; } break; } if (!dn) { error = "--dn is required"; goto usage; } id = identification_create_from_string(dn); if (id->get_type(id) != ID_DER_ASN1_DN) { error = "supplied --dn is not a distinguished name"; goto end; } if (file) { private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type, BUILD_FROM_FILE, file, BUILD_END); }
/** * See header. */ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, va_list args) { chunk_t asn1; char *label; u_char *pos; size_t len, written, pem_chars, pem_lines; chunk_t n, e, d, p, q, exp1, exp2, coeff, to_free = chunk_empty; switch (type) { case PUBKEY_PEM: label ="PUBLIC KEY"; /* direct PKCS#1 PEM encoding */ if (cred_encoding_args(args, CRED_PART_RSA_PUB_ASN1_DER, &asn1, CRED_PART_END) || cred_encoding_args(args, CRED_PART_ECDSA_PUB_ASN1_DER, &asn1, CRED_PART_END) || cred_encoding_args(args, CRED_PART_EDDSA_PUB_ASN1_DER, &asn1, CRED_PART_END) || cred_encoding_args(args, CRED_PART_BLISS_PUB_ASN1_DER, &asn1, CRED_PART_END)) { break; } /* indirect PEM encoding from components */ if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n, CRED_PART_RSA_PUB_EXP, &e, CRED_PART_END)) { if (lib->encoding->encode(lib->encoding, PUBKEY_SPKI_ASN1_DER, NULL, &asn1, CRED_PART_RSA_MODULUS, n, CRED_PART_RSA_PUB_EXP, e, CRED_PART_END)) { to_free = asn1; break; } } return FALSE; case PRIVKEY_PEM: label ="RSA PRIVATE KEY"; /* direct PKCS#1 PEM encoding */ if (cred_encoding_args(args, CRED_PART_RSA_PRIV_ASN1_DER, &asn1, CRED_PART_END)) { break; } /* indirect PEM encoding from components */ if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n, CRED_PART_RSA_PUB_EXP, &e, CRED_PART_RSA_PRIV_EXP, &d, CRED_PART_RSA_PRIME1, &p, CRED_PART_RSA_PRIME2, &q, CRED_PART_RSA_EXP1, &exp1, CRED_PART_RSA_EXP2, &exp2, CRED_PART_RSA_COEFF, &coeff, CRED_PART_END)) { if (lib->encoding->encode(lib->encoding, PRIVKEY_ASN1_DER, NULL, &asn1, CRED_PART_RSA_MODULUS, n, CRED_PART_RSA_PUB_EXP, e, CRED_PART_RSA_PRIV_EXP, d, CRED_PART_RSA_PRIME1, p, CRED_PART_RSA_PRIME2, q, CRED_PART_RSA_EXP1, exp1, CRED_PART_RSA_EXP2, exp2, CRED_PART_RSA_COEFF, coeff, CRED_PART_END)) { to_free = asn1; break; } } if (cred_encoding_args(args, CRED_PART_ECDSA_PRIV_ASN1_DER, &asn1, CRED_PART_END)) { label ="EC PRIVATE KEY"; break; } if (cred_encoding_args(args, CRED_PART_BLISS_PRIV_ASN1_DER, &asn1, CRED_PART_END)) { label ="BLISS PRIVATE KEY"; break; } if (cred_encoding_args(args, CRED_PART_EDDSA_PRIV_ASN1_DER, &asn1, CRED_PART_END)) { label ="PRIVATE KEY"; break; } return FALSE; case CERT_PEM: if (cred_encoding_args(args, CRED_PART_X509_ASN1_DER, &asn1, CRED_PART_END)) { /* PEM encode x509 certificate */ label = "CERTIFICATE"; break; } if (cred_encoding_args(args, CRED_PART_X509_CRL_ASN1_DER, &asn1, CRED_PART_END)) { /* PEM encode CRL */ label = "X509 CRL"; break; } if (cred_encoding_args(args, CRED_PART_PKCS10_ASN1_DER, &asn1, CRED_PART_END)) { /* PEM encode PKCS10 certificate reqeuest */ label = "CERTIFICATE REQUEST"; break; } if (cred_encoding_args(args, CRED_PART_X509_AC_ASN1_DER, &asn1, CRED_PART_END)) { label = "ATTRIBUTE CERTIFICATE"; break; } default: return FALSE; } /* compute and allocate maximum size of PEM object */ pem_chars = 4 * ((asn1.len + 2) / 3); pem_lines = (asn1.len + BYTES_PER_LINE - 1) / BYTES_PER_LINE; *encoding = chunk_alloc(5 + 2*(6 + strlen(label) + 6) + 3 + pem_chars + pem_lines); pos = encoding->ptr; len = encoding->len; /* write PEM header */ written = snprintf(pos, len, "-----BEGIN %s-----\n", label); pos += written; len -= written; /* write PEM body */ while (pem_lines--) { chunk_t asn1_line, pem_line; asn1_line = chunk_create(asn1.ptr, min(asn1.len, BYTES_PER_LINE)); asn1.ptr += asn1_line.len; asn1.len -= asn1_line.len; pem_line = chunk_to_base64(asn1_line, pos); pos += pem_line.len; len -= pem_line.len; *pos = '\n'; pos++; len--; } chunk_clear(&to_free); /* write PEM trailer */ written = snprintf(pos, len, "-----END %s-----", label); pos += written; len -= written; /* replace termination null character with newline */ *pos = '\n'; pos++; len--; /* compute effective length of PEM object */ encoding->len = pos - encoding->ptr; return TRUE; }