Esempio n. 1
0
static selene_error_t *
sln_io_alert(selene_t *s, sln_alert_level_e level, sln_alert_description_e desc)
{
  sln_bucket_t *btls = NULL;
  sln_bucket_t *balert = NULL;
  sln_msg_alert_t alert;
  sln_msg_tls_t tls;

  alert.level =  level;
  alert.description = desc;

  SELENE_ERR(sln_alert_unparse(s, &alert, &balert));

  tls.content_type = SLN_CONTENT_TYPE_ALERT;
  tls.version_major = 3;
  tls.version_minor = 1;
  tls.length = balert->size;

  SELENE_ERR(sln_tls_unparse_header(s, &tls, &btls));

  SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, btls);

  SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, balert);

  return SELENE_SUCCESS;
}
Esempio n. 2
0
/* Based on Node's SSL_CTX_use_certificate_chain, in src/node_crypto.cc */
selene_error_t *read_certificate_chain(selene_conf_t *conf, BIO *in,
                                       selene_cert_chain_t **p_certs) {
  X509 *x = NULL;
  selene_cert_chain_t *chain;
  selene_cert_t *tmpc;

  x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);

  if (x == NULL) {
    return selene_error_create(SELENE_ENOMEM, "Failed to parse certificate");
  }

  SELENE_ERR(sln_cert_chain_create(conf, &chain));
  SELENE_ERR(sln_cert_create(conf, x, 0, &tmpc));
  SLN_CERT_CHAIN_INSERT_TAIL(chain, tmpc);

  {
    /**
     * If we could set up our certificate, now proceed to
     * the CA certificates.
     */
    X509 *ca;
    unsigned long err;

    while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
      SELENE_ERR(sln_cert_create(conf, ca, 0, &tmpc));
      SLN_CERT_CHAIN_INSERT_TAIL(chain, tmpc);
    }

    /* When the while loop ends, it's usually just EOF. */
    err = ERR_peek_last_error();
    if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
        ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
      ERR_clear_error();
    } else {
      /* some real error */
      /* TODO: handle parse errors of the ca certs */
      ERR_clear_error();
    }
  }

  *p_certs = chain;

  return SELENE_SUCCESS;
}
Esempio n. 3
0
selene_error_t *sln_tls_toss_bucket(selene_t *s,
                                    sln_content_type_e content_type,
                                    sln_bucket_t *bout) {
  sln_msg_tls_t tls;
  sln_parser_baton_t *baton = s->backend_baton;
  sln_bucket_t *btls = NULL;
  sln_bucket_t *benc = NULL;

  if (content_type == SLN_CONTENT_TYPE_HANDSHAKE) {
    sln_digest_update(baton->md5_handshake_digest, bout->data, bout->size);
    sln_digest_update(baton->sha1_handshake_digest, bout->data, bout->size);
  }

  SELENE_ERR(sln_tls_params_update_mac(s, bout));

  SELENE_ERR(sln_tls_params_encrypt(s, bout, &benc));

  tls.content_type = content_type;
  sln_parser_tls_set_current_version(s, &tls.version_major, &tls.version_minor);
  if (benc != NULL) {
    tls.length = benc->size;
  } else {
    tls.length = bout->size;
  }

  SELENE_ERR(sln_tls_serialize_header(s, &tls, &btls));

  SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, btls);
  if (benc != NULL) {
    SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, benc);
  } else {
    SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, bout);
  }

  return SELENE_SUCCESS;
}
Esempio n. 4
0
static selene_error_t *have_cleartext(selene_t *s, selene_event_e event,
                                      void *baton) {
  char buf[8096];
  size_t blen = 0;
  size_t remaining = 0;

  do {
    SELENE_ERR(
        selene_io_out_clear_bytes(s, &buf[0], sizeof(buf), &blen, &remaining));

    if (blen > 0) {
      fwrite(buf, blen, 1, stdout);
      fflush(stdout);
    }
  } while (remaining > 0);

  return SELENE_SUCCESS;
}
Esempio n. 5
0
selene_error_t *selene_conf_cert_chain_add(selene_conf_t *conf,
                                           const char *certificate,
                                           const char *pkey) {
  selene_cert_chain_t *certs = NULL;
  BIO *bio = BIO_new(BIO_s_mem());

  int r = BIO_write(bio, certificate, strlen(certificate));
  if (r <= 0) {
    BIO_free(bio);
    return selene_error_createf(
        SELENE_ENOMEM,
        "Attempting to parse Cert Chain certificate, BIO_write returned: %d",
        r);
  }

  /* TODO: private key */
  SELENE_ERR(read_certificate_chain(conf, bio, &certs));

  SLN_ARRAY_PUSH(conf->certs, selene_cert_chain_t *) = certs;

  return SELENE_SUCCESS;
}
Esempio n. 6
0
static selene_error_t *want_pull(selene_t *s, selene_event_e event,
                                 void *baton) {
  int rv = 0;
  char buf[8096];
  size_t blen = 0;
  size_t remaining = 0;
  server_t *srv = (server_t *)baton;

  do {
    SELENE_ERR(
        selene_io_out_enc_bytes(s, &buf[0], sizeof(buf), &blen, &remaining));

    if (blen > 0) {
      setblocking(srv->sock);
      rv = write(srv->sock, buf, blen);
      if (rv < 0) {
        srv->write_err = errno;
        break;
      }
    }
  } while (remaining > 0);

  return SELENE_SUCCESS;
}
Esempio n. 7
0
selene_error_t *
selene_conf_use_reasonable_defaults(selene_conf_t *conf)
{
  selene_cipher_suite_list_t *ciphers = NULL;
  SELENE_ERR(selene_cipher_suite_list_create(&ciphers));

  SELENE_ERR(selene_cipher_suite_list_add(ciphers, SELENE_CS_RSA_WITH_RC4_128_SHA));
  SELENE_ERR(selene_cipher_suite_list_add(ciphers, SELENE_CS_RSA_WITH_AES_128_CBC_SHA));
  SELENE_ERR(selene_cipher_suite_list_add(ciphers, SELENE_CS_RSA_WITH_AES_256_CBC_SHA));

  SELENE_ERR(selene_conf_cipher_suites(conf, ciphers));

  selene_cipher_suite_list_destroy(ciphers);

  SELENE_ERR(selene_conf_protocols(conf, SELENE_PROTOCOL_SSL30 | 
                                         SELENE_PROTOCOL_TLS10 |
                                         SELENE_PROTOCOL_TLS11 |
                                         SELENE_PROTOCOL_TLS12));

  return SELENE_SUCCESS;
}
Esempio n. 8
0
selene_error_t*
sln_native_handshake_state_machine(selene_t *s, sln_native_baton_t *baton)
{
  selene_error_t* err;

enter_state_machine:
  slnDbg(s, "enter handshake_state_machine=%d", baton->handshake);
  switch (baton->handshake) {
    case SLN_NATIVE_HANDSHAKE_CLIENT_SEND_HELLO:
      err = sln_native_io_handshake_client_hello(s, baton);
      if (err) {
        return err;
      }
      baton->handshake = SLN_NATIVE_HANDSHAKE_CLIENT_WAIT_SERVER_HELLO_DONE;
      break;
    case SLN_NATIVE_HANDSHAKE_CLIENT_WAIT_SERVER_HELLO_DONE:
      break;
    case SLN_NATIVE_HANDSHAKE_CLIENT_SEND_FINISHED:
      break;
    case SLN_NATIVE_HANDSHAKE_CLIENT_WAIT_SERVER_FINISHED:
      break;
    case SLN_NATIVE_HANDSHAKE_CLIENT_APPDATA:
      break;

    /***
     * Start Server Methods.
     */
    case SLN_NATIVE_HANDSHAKE_SERVER_WAIT_CLIENT_HELLO:

      if (!SLN_BRIGADE_EMPTY(s->bb.in_enc)) {
        err = sln_native_io_tls_read(s, baton);
        if (err) {
          return err;
        }
      }

      if (!SLN_BRIGADE_EMPTY(baton->in_handshake)) {
        err = sln_native_io_handshake_read_client_hello(s, baton);
        if (err) {
          return err;
        }
        if (baton->handshake != SLN_NATIVE_HANDSHAKE_SERVER_WAIT_CLIENT_HELLO) {
          goto enter_state_machine;
        }
      }
      break;
    case SLN_NATIVE_HANDSHAKE_SERVER_SEND_SERVER_HELLO_DONE:
      break;
    case SLN_NATIVE_HANDSHAKE_SERVER_WAIT_CLIENT_FINISHED:
      break;
    case SLN_NATIVE_HANDSHAKE_SERVER_SNED_FINISHED:
      break;
    case SLN_NATIVE_HANDSHAKE_SERVER_APPDATA:
      break;

    case SLN_NATIVE_HANDSHAKE__UNUSED0:
    case SLN_NATIVE_HANDSHAKE__MAX:
      /* TODO: better handle this */
      abort();
      break;
    //default:
  }

  if (!SLN_BRIGADE_EMPTY(s->bb.out_enc)) {
    slnDbg(s, "Encrypted data waiting");
    SELENE_ERR(selene_publish(s, SELENE_EVENT_IO_OUT_ENC));
  }

  if (!SLN_BRIGADE_EMPTY(s->bb.out_cleartext)) {
    slnDbg(s, "Cleartext data waiting");
    SELENE_ERR(selene_publish(s, SELENE_EVENT_IO_OUT_CLEAR));
  }

  slnDbg(s, "exit handshake_state_machine=%d", baton->handshake);
  return SELENE_SUCCESS;
}