selene_error_t *sln_cryptor_osx_cc_create(selene_t *s, int encrypt,
                                          sln_cipher_e type, const char *key,
                                          const char *iv,
                                          sln_cryptor_t **p_enc) {
  CCCryptorStatus rv;
  CCCryptorRef cryptor;
  size_t keylen;
  CCAlgorithm alg;
  CCOperation op;

  if (encrypt) {
    op = kCCEncrypt;
  } else {
    op = kCCDecrypt;
  }
  switch (type) {
    case SLN_CIPHER_AES_128_CBC:
      alg = kCCAlgorithmAES128;
      keylen = kCCKeySizeAES128;
      break;
    case SLN_CIPHER_AES_256_CBC:
      /* TODO: it is not clear from the docs why this is named AES-128, but if
       * you
       * pass in a key size that is for AES-256, it works (?????) as if it was
       * in AES-256 mode (!!!!!)
       */
      alg = kCCAlgorithmAES128;
      keylen = kCCKeySizeAES256;
      break;
    case SLN_CIPHER_RC4:
      alg = kCCAlgorithmRC4;
      keylen = SLN_CIPHER_RC4_128_KEY_LENGTH;
      break;
    default:
      return selene_error_createf(SELENE_ENOTIMPL,
                                  "Unsupported cipher type: %d", type);
  }

  rv = CCCryptorCreate(op, alg, 0, key, keylen, iv, &cryptor);

  if (rv != kCCSuccess) {
    return selene_error_createf(
        SELENE_EIO, "CCCryptorCreate failed CCCryptorStatus=%d", rv);
  } else {
    sln_cryptor_t *enc = sln_alloc(s, sizeof(sln_cryptor_t));
    enc->s = s;
    enc->baton = cryptor;
    enc->type = type;
    *p_enc = enc;
  }

  return SELENE_SUCCESS;
}
Beispiel #2
0
selene_error_t *sln_tls_serialize_header(selene_t *s, sln_msg_tls_t *tls,
                                         sln_bucket_t **p_b) {
  sln_bucket_t *b = NULL;

  size_t len = 5;

  sln_bucket_create_empty(s->alloc, &b, len);

  switch (tls->content_type) {
    case SLN_CONTENT_TYPE_CHANGE_CIPHER_SPEC:
      b->data[0] = 0x14;
      break;
    case SLN_CONTENT_TYPE_ALERT:
      b->data[0] = 0x15;
      break;
    case SLN_CONTENT_TYPE_HANDSHAKE:
      b->data[0] = 0x16;
      break;
    case SLN_CONTENT_TYPE_APPLICATION:
      b->data[0] = 0x17;
      break;
    default:
      return selene_error_createf(SELENE_EINVAL, "Unknown content type: %d",
                                  tls->content_type);
  }

  b->data[1] = tls->version_major;
  b->data[2] = tls->version_minor;
  b->data[3] = tls->length >> 8;
  b->data[4] = tls->length;

  *p_b = b;

  return SELENE_SUCCESS;
}
Beispiel #3
0
selene_error_t*
selene_conf_ca_trusted_cert_add(selene_conf_t *conf, const char *certificate)
{
  /* TOOD: replace with native x509 :( )*/
  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 CA certificate, BIO_write returned: %d", r);
  }

  X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
  if (!x509) {
    BIO_free(bio);
    /* TODO: better error messages */
    return selene_error_create(SELENE_ENOMEM, "Attempting to parse CA certificate, PEM_read_bio_X509 failed.");
  }

  BIO_free(bio);

  X509_STORE_add_cert(conf->trusted_cert_store, x509);

  return SELENE_SUCCESS;
}
Beispiel #4
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;
}