static void tls_http_accident(void **state) { selene_error_t *err; sln_parser_baton_t *baton; selene_conf_t *conf = NULL; selene_t *s = NULL; http_cb_t cbb; sln_bucket_t *e1; init_ctxt(state, &s, &conf); baton = (sln_parser_baton_t *)s->backend_baton; cbb.gotit = 0; selene_handler_set(s, SELENE_EVENT_TLS_GOT_HTTP, http_cb, &cbb); SLN_ERR(sln_bucket_create_copy_bytes(sln_test_alloc, &e1, http_message, strlen(http_message))); SLN_BRIGADE_INSERT_TAIL(s->bb.in_enc, e1); err = sln_io_tls_read(s, baton); SLN_ASSERT(err != NULL); SLN_ASSERT(err->err == SELENE_EINVAL); selene_error_clear(err); assert_int_equal(1, cbb.gotit); destroy_ctxt(state, s, conf); }
selene_error_t *sln_handshake_serialize_finished(selene_t *s, sln_msg_finished_t *fin, sln_bucket_t **p_b) { sln_bucket_t *b = NULL; size_t len = 0; size_t off = 0; /* message type size */ len += 1; /* length size */ len += 3; /* verify data size */ len += SLN_MSG_FINISHED_VERIFY_LENGTH; sln_bucket_create_empty(s->alloc, &b, len); b->data[off] = SLN_HS_MT_FINISHED; off += 1; b->data[off] = SLN_MSG_FINISHED_VERIFY_LENGTH >> 16; b->data[off + 1] = SLN_MSG_FINISHED_VERIFY_LENGTH >> 8; b->data[off + 2] = SLN_MSG_FINISHED_VERIFY_LENGTH; off += 3; memcpy(b->data + off, fin->vdata, SLN_MSG_FINISHED_VERIFY_LENGTH); off += SLN_MSG_FINISHED_VERIFY_LENGTH; SLN_ASSERT(off == len); *p_b = b; return SELENE_SUCCESS; }
static void tls_io_slowly(void **state) { selene_error_t *err; sln_parser_baton_t *baton; selene_conf_t *conf = NULL; selene_t *s = NULL; sln_bucket_t *e1; size_t maxlen = sizeof(openssl_client_hello_basic); size_t i; init_ctxt(state, &s, &conf); baton = (sln_parser_baton_t *)s->backend_baton; for (i = 0; i <= maxlen; i++) { SLN_ERR(sln_bucket_create_copy_bytes( sln_test_alloc, &e1, (const char *)openssl_client_hello_basic, i)); SLN_BRIGADE_INSERT_TAIL(s->bb.in_enc, e1); err = sln_io_tls_read(s, baton); if (err) { SLN_ASSERT(err->err == SELENE_EINVAL); } else if (baton->peer_version_major != 0) { assert_int_equal(baton->peer_version_major, 3); assert_int_equal(baton->peer_version_minor, 1); } sln_brigade_clear(baton->in_handshake); sln_brigade_clear(s->bb.in_enc); } destroy_ctxt(state, s, conf); }
static void handshake_io_slowly(void **state) { selene_error_t *err; sln_parser_baton_t *baton; selene_conf_t *conf = NULL; selene_t *s = NULL; sln_bucket_t *e1; size_t maxlen = sizeof(openssl_client_hello_basic); size_t i; selene_conf_create(&conf); SLN_ERR(selene_conf_use_reasonable_defaults(conf)); SLN_ERR(selene_server_create(conf, &s)); SLN_ASSERT_CONTEXT(s); baton = (sln_parser_baton_t *)s->backend_baton; for (i = maxlen; i <= maxlen; i++) { SLN_ERR(sln_bucket_create_copy_bytes(sln_test_alloc, &e1, openssl_client_hello_basic, i)); SLN_BRIGADE_INSERT_TAIL(baton->in_handshake, e1); err = sln_io_handshake_read(s, baton); if (err) { SLN_ASSERT(err->err == SELENE_EINVAL); } else { /* TODO: more asserts */ } sln_brigade_clear(baton->in_handshake); } selene_destroy(s); selene_conf_destroy(conf); }
const char *sln_tests_load_cert(const char *fname) { char p[PATHMAX]; FILE *fp; struct stat s; char *buf; snprintf(p, sizeof(p), "%s/../../../tests/fixtures/%s", testdir_path, fname); fp = fopen(p, "r"); SLN_ASSERT(fp != NULL); stat(p, &s); buf = malloc(s.st_size + 1); fread(buf, s.st_size, 1, fp); buf[s.st_size] = '\0'; fclose(fp); return buf; }
selene_error_t *sln_tok_parser(sln_brigade_t *bb, sln_tok_cb cb, void *baton) { int keepgoing = 1; selene_error_t *err = SELENE_SUCCESS; sln_tok_value_t tvalue; size_t rlen; size_t offset = 0; sln_brigade_t *tmpbb = NULL; memset(&tvalue, 0, sizeof(tvalue)); tvalue.next = TOK_INIT; while (keepgoing == 1) { tvalue.current = tvalue.next; err = cb(&tvalue, baton); if (err) { break; } switch (tvalue.next) { case TOK__UNUSED: case TOK__MAX: case TOK_INIT: case TOK_DONE: keepgoing = 0; break; case TOK_SKIP: if (tvalue.wantlen > sln_brigade_size(bb)) { keepgoing = 0; break; } break; case TOK_UINT16: SLN_ASSERT(tvalue.wantlen == 2); err = sln_brigade_pread_bytes(bb, offset, tvalue.wantlen, &tvalue.v.bytes[0], &rlen); if (err) { keepgoing = 0; break; } if (rlen != tvalue.wantlen) { keepgoing = 0; break; } tvalue.v.uint16 = (((unsigned char)tvalue.v.bytes[0]) << 8 | ((unsigned char)tvalue.v.bytes[1])); break; case TOK_UINT24: SLN_ASSERT(tvalue.wantlen == 3); err = sln_brigade_pread_bytes(bb, offset, tvalue.wantlen, &tvalue.v.bytes[0], &rlen); if (err) { keepgoing = 0; break; } if (rlen != tvalue.wantlen) { keepgoing = 0; break; } tvalue.v.uint24 = (((unsigned char)tvalue.v.bytes[0]) << 16 | ((unsigned char)tvalue.v.bytes[1]) << 8 | ((unsigned char)tvalue.v.bytes[2])); break; case TOK_COPY_BYTES: SLN_ASSERT(tvalue.wantlen <= SLN_TOK_VALUE_MAX_BYTE_COPY_LEN); err = sln_brigade_pread_bytes(bb, offset, tvalue.wantlen, &tvalue.v.bytes[0], &rlen); if (err) { keepgoing = 0; break; } if (rlen != tvalue.wantlen) { keepgoing = 0; } break; case TOK_COPY_BRIGADE: if (tvalue.wantlen > sln_brigade_size(bb)) { keepgoing = 0; break; } if (tmpbb == NULL) { err = sln_brigade_create(bb->alloc, &tmpbb); if (err) { keepgoing = 0; break; } } else { sln_brigade_clear(tmpbb); } tvalue.v.bb = tmpbb; /* TODO: optimization, this isn't required */ err = sln_brigade_copy_into(bb, offset, tvalue.wantlen, tmpbb); if (err) { keepgoing = 0; break; } break; } offset += tvalue.wantlen; tvalue.current = TOK__UNUSED; } if (tmpbb != NULL) { sln_brigade_destroy(tmpbb); } return err; }